我是Rust的新手,观察到了我无法反对的内容。
当我写
fn main() {
('a'..'z').all(|_| true);
}
编译器报告错误:
error[E0599]: no method named `all` found for type `std::ops::Range<char>` in the current scope
--> src/main.rs:2:16
|
2 | ('a'..'z').all(|_| true)
| ^^^
|
= note: the method `all` exists but the following trait bounds were not satisfied:
`std::ops::Range<char> : std::iter::Iterator`
当我将其更改为
fn main() {
(b'a'..b'z').all(|_| true);
}
它会编译。
这是怎么回事? Rust说the method ... exists but the following trait bounds were not satisfied
时是什么意思?
答案 0 :(得分:4)
方法all()
是具有Iterator
特性的方法,因此您只能在实现该特性的类型上调用它。类型Range<char>
没有实现Iterator
特征,因为在通常情况下,Unicode字符的范围不是很好定义的。有效的Unicode代码点集存在空白,并且通常认为构建一系列代码点是无用的。另一方面,类型Range<u8>
确实实现了Iterator
,因为在一定范围的字节上进行迭代具有明确的含义。
更一般地,错误消息告诉您Rust找到了具有正确名称的方法,但该方法不适用于您为其调用的类型。
答案 1 :(得分:2)
这意味着范围中有一个具有该名称功能的特性,但是您使用的对象没有实现这种特性。
在您的特定情况下,包含all
方法的特征是std::iter::Iterator
,但是如果对象('a'..'z')
的类型为Range<char>
,则它不能实现。 >
奇怪的是,您的第二个示例可以编译,因为(b'a'..b'z')
的类型为Range<u8>
,但确实实现了Iterator
。
您可能想知道为什么Range<char>
不实现迭代器。那是因为有效值之间存在无效的char
值,因此这些范围只是不能迭代的。特别是,唯一有效的字符是IIRC [0x0, 0xD7FF]
和[0xE000, 0x10FFFF]
范围内的字符。