为什么不能收集一系列的char?

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)

这是奇怪的,因为据我了解,有一个铺盖实现IteratorRangeInclusive.

是否不可能使用一系列字符作为迭代器?如果是这样,为什么?如果没有,我做错了什么?我正在使用稳定的Rust 2018 1.31.1.

Luk*_*odt 7

表达式b'a'..=b'z'具有类型RangeInclusive<u8>(请参阅Playground),因为表达式b'a'具有以下类型u8:这就是b字符文字前面的内容.另一方面,表达式'a'..='z'(没有bs)具有类型RangeInclusive<char>.

[...]有一个毯子实现IteratorRangeInclusive.

首先,这不是我们所说的"一揽子实现"(这是当impl块是for Tfor &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不会出现两次.