当“方法存在但特质界限不满足”时,这是什么意思?

时间:2019-05-24 17:04:44

标签: rust

我是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时是什么意思?

2 个答案:

答案 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]范围内的字符。