为什么不能收集一定范围的字符? [英] Why can't a range of char be collected?

查看:68
本文介绍了为什么不能收集一定范围的字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试生成一个包含小写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 bs) has the type RangeInclusive<char>.

[...]为RangeInclusive提供了Iterator的全面实现.

[...] there is a blanket implementation of Iterator for RangeInclusive.

对于一个,这不是我们所谓的空白实现"(这是当impl块是for Tfor &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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆