为什么不能收集一定范围的字符? [英] Why can't a range of char be collected?
问题描述
我正在尝试生成一个包含小写ASCII字符的向量.这种更复杂的方法有效:
I'm trying to generate a vector containing lowercase ASCII characters. This more convoluted approach works:
let ascii_lowercase = (b'a'..=b'z').map(|b| b as char).collect::<Vec<char>>();
但是我首先想到的这个更简单的方法却没有:
But this more straightforward one, which I came up with in the first place, does not:
let ascii_lowercase = ('a'..='z').collect::<Vec<char>>();
错误是:
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`
这很奇怪,因为据我了解,有一个针对RangeInclusive
的Iterator
的全面实现.
Which is weird, because as far as I understand, there is a blanket implementation of Iterator
for RangeInclusive
.
是否可以将一系列字符用作迭代器?如果是这样,为什么?如果没有,我在做什么错?我正在使用稳定的Rust 2018 1.31.1.
Is it impossible to use a range of chars as an iterator? If so, why? If not, what am I doing wrong? I'm using stable Rust 2018 1.31.1.
推荐答案
表达式b'a'..=b'z'
具有类型RangeInclusive<u8>
(
The expression b'a'..=b'z'
has the type RangeInclusive<u8>
(see on Playground) because the expression b'a'
has the type u8
: that's what the b
in front of the character literal is for. On the other hand, the expression 'a'..='z'
(without the b
s) has the type RangeInclusive<char>
.
[...]为
RangeInclusive
提供了Iterator
的全面实现.
[...] there is a blanket implementation of
Iterator
forRangeInclusive
.
对于一个,这不是我们所谓的空白实现"(这是当impl块是for T
或for &T
(或类似),而T
是泛型类型时).但是是的,有一个暗示.但是,让我们仔细看看:
For one, this is not what we call "blanket implementation" (this is when the impl block is for T
or for &T
(or similar) with T
being a generic type). But yes, there is an impl. But let's take a closer look:
impl<A> Iterator for RangeInclusive<A>
where
A: Step, // <--- important
A: Step
边界很重要.如您在 Step
文档中所见,特质适用于所有原始整数类型,但不适用于char
.这意味着对字符没有明确的加一"操作.是的,您可以可以将其定义为下一个有效的Unicode代码点,但是Rust开发人员可能有充分的理由对此表示反对.
The A: Step
bound is important. As you can see in the documentation for Step
, this trait is implemented for all primitive integer types, but not for char
. This means that there is no clear "add one" operation on characters. Yes, you could define it to be the next valid Unicode codepoint, but the Rust developers probably decided against that for a good reason.
因此, RangeInclusive<char>
没有实现Iterator
.
As a consequence, RangeInclusive<char>
does not implement Iterator
.
因此您的解决方案已经是一个不错的解决方案.我可能会这样写:
So your solution is already a good one. I would probably write this:
(b'a'..=b'z').map(char::from).collect::<Vec<_>>()
唯一的真正好处是,在此版本中,char
不会出现两次.
The only real advantage is that in this version, char
doesn't appear twice.
这篇关于为什么不能收集一定范围的字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!