为什么num :: One需要迭代一个范围?

Aut*_*act 2 rust

为什么以下带有char范围的循环无法编译?

fn main() {
    for c in 'a'..'z' {
        println!("{}", c);
    }
}
Run Code Online (Sandbox Code Playgroud)

错误...

main.rs:11:5: 14:2 error: the trait `core::num::One` is not implemented for the type `char` [E0277]
main.rs:11     for c in 'a'..'z' {
main.rs:12         println!("{}", c);
main.rs:13     }
main.rs:14 }
main.rs:11:5: 14:2 error: the trait `core::iter::Step` is not implemented for the type `char` [E0277]
main.rs:11     for c in 'a'..'z' {
main.rs:12         println!("{}", c);
main.rs:13     }
main.rs:14 }
Run Code Online (Sandbox Code Playgroud)

为什么你甚至需要core::num::One迭代一个范围?

huo*_*uon 7

x..y语法糖std::ops::Range { start: x, end: y }.这个type(Range<A>)是可迭代的,Iterator因为它的实现,特别是从该页面:

impl<A> Iterator for Range<A>
   where A: One + Step,
         &'a A: Add<&'a A>,
         &'a A::Output == A {
    type Item = A;
Run Code Online (Sandbox Code Playgroud)

这是说,Range<A>可以表现为一个迭代过A,如果S型A器具OneStep,并能以正确的方式加入.

在这种情况下,char不满足任何一个:它在语义上是无意义的char,One或者是可添加的,并且它也没有实现Step.

也就是说,因为char没有实现这些特性(因此Range<char>不会像通过那样的迭代器impl),所以应该可以有一个手动impl:

impl Iterator for Range<char> {
    type Item = char;
Run Code Online (Sandbox Code Playgroud)

这将允许for x in 'a'..'z'工作.

然而,这可能在语义上不是我们想要的:..范围不包括最后一个元素,这对于字符来说是令人惊讶的,人们必须编写'a'..'{'以获得字母A到Z.有包含范围语法的提议,例如一个例子是'a'...'z'(更多的点==更多的元素),我想这将有一个s Iterator类型的实现char.

正如其他人已经证明的那样,对于ASCII字符,可以使用字节文字,更一般地说,可以将字符转换为u32s:

for i in ('à' as u32)..('æ' as u32) + 1 {
    let c = std::char::from_u32(i).unwrap();
    println!("{}", c);
}
Run Code Online (Sandbox Code Playgroud)

这使:

à
á
â
ã
ä
å
æ
Run Code Online (Sandbox Code Playgroud)

NB.这种方法并不完美,如果范围越过代理范围0xD800-0xDFFF ,它将崩溃.

我刚刚发布了一个箱子,char-iter它可以正确处理后者并且表现得像人们预期的那样.一旦添加(通过货物),它可以像:

extern crate char_iter;
// ...

for c in char_iter::new('a', 'z') {
    // ...
}
for c in char_iter::new('à', 'æ') {
    // ...
}
Run Code Online (Sandbox Code Playgroud)