dlu*_*kes 4 collections iterator rust
我正在尝试生成包含小写ASCII字符的向量.这种更复杂的方法有效:
let ascii_lowercase = (b'a'..=b'z').map(|b| b as char).collect::<Vec<char>>();
Run Code Online (Sandbox Code Playgroud)
但是,我首先提出的这个更直接的方法并不是:
let ascii_lowercase = ('a'..='z').collect::<Vec<char>>();
Run Code Online (Sandbox Code Playgroud)
错误是:
error[E0599]: no method named `collect` found for type `std::ops::RangeInclusive<char>` in the current scope
--> src/main.rs:2:39
|
2 | let ascii_lowercase = ('a'..='z').collect::<Vec<char>>();
| ^^^^^^^
|
= note: the method `collect` exists but the following trait bounds were not satisfied:
`std::ops::RangeInclusive<char> : std::iter::Iterator`
`&mut std::ops::RangeInclusive<char> : std::iter::Iterator`
Run Code Online (Sandbox Code Playgroud)
这是奇怪的,因为据我了解,有一个铺盖实现Iterator的RangeInclusive.
是否不可能使用一系列字符作为迭代器?如果是这样,为什么?如果没有,我做错了什么?我正在使用稳定的Rust 2018 1.31.1.
表达式b'a'..=b'z'具有类型RangeInclusive<u8>(请参阅Playground),因为表达式b'a'具有以下类型u8:这就是b字符文字前面的内容.另一方面,表达式'a'..='z'(没有bs)具有类型RangeInclusive<char>.
[...]有一个毯子实现
Iterator了RangeInclusive.
首先,这不是我们所说的"一揽子实现"(这是当impl块是for T或for &T(或类似)T为泛型类型时).但是,是的,有一个impl.但让我们仔细看看:
impl<A> Iterator for RangeInclusive<A>
where
A: Step, // <--- important
Run Code Online (Sandbox Code Playgroud)
该A: Step界是非常重要的.正如您在文档中Step看到的,此特征是针对所有原始整数类型实现的,但不适用于char.这意味着字符上没有明确的"添加一个"操作.是的,您可以将其定义为下一个有效的Unicode代码点,但Rust开发人员可能会出于某种原因决定反对这一点.
因此,RangeInclusive<char>没有实施Iterator.
所以你的解决方案已经很好了.我可能会写这个:
(b'a'..=b'z').map(char::from).collect::<Vec<_>>()
Run Code Online (Sandbox Code Playgroud)
唯一真正的优点是在这个版本中,char不会出现两次.