let x = "hello".chars().rev().collect();
// The compiler could not infer a type and asked for a type annotation.
This error indicates that type inference did not result in one unique possible type, and extra information is required. In most cases this can be provided by adding a type annotation. Sometimes you need to specify a generic type parameter manually.
A common example is the collect method on Iterator. It has a generic type parameter with a FromIterator bound, which for a char iterator is implemented by Vec and String among others. Consider the following snippet that reverses the characters of a string:
In the first code example, the compiler cannot infer what the type of x should be: Vec and String are both suitable candidates. To specify which type to use, you can use a type annotation on x:
let x: Vec = “hello”.chars().rev().collect();
It is not necessary to annotate the full type. Once the ambiguity is resolved, the compiler can infer the rest:
let x: Vec<_> = “hello”.chars().rev().collect();
iter::Iterator
fn rev(self) -> Rev where Self: DoubleEndedIterator
对于实现了 DoubleEndedIteator 的 Self, 调用此方法返回 Rev
Iterator trait 为 DoubleEndedIterator trait 的 super trait.(这要求实现 DobuleEndedItrator 的 Selft 必须也实现了 Iterator). DoubleEndedIterator 为 Rev 结构体提供了实现。
Chars<'a> 实现了 DoubleEndedIterator,同时 Chars<'a> 又实现了 Iterator
impl<'a> Iterator for Chars<'a>
type Item = char
所以 "abc".chars().rev().collect |-> Rev | ↓ ↓ Iterator 的方法
Rev 是结构体,有私有字段,实现了
impl<I> DoubleEndedIterator for Rev<I>where
I: DoubleEndedIterator,
可以调用 Iterator 的 collect 方法
fn collect<B>(self) -> B
where
B: FromIterator<Selft::Item>
这里要指定 B 的类型,这里为 FromIterator trait 实现的类型。
查看 FromIterator trait
impl FromIterator<char> for String // 特定实现
impl<T> FromIterator<T> for Vec<T, Global> // T 为泛型,包含 char
impl<T> FromIterator<T> for Rc<[T]>
...
由此可见 FromIterator 有不止两个实现。所以要明确指定,不然编译器无法确定最终类型。
以下都可以,只要编译器能推断出来,就可以省略点什么。
let x: Vec<char> = "hello".chars().rev().collect();
let x: Vec<_> = "hello".chars().rev().collect();
let x = "hello".chars().rev().collect::<Vec<char>>();
let x = "hello".chars().rev().collect::<Vec<_>>();
所以 among others 的意思是这里指的是除了 Vec<_> 和 String 还有其他的 FromIterator 实现可作为候选项,所以要明确指定最终类型。