![](/img/trans.png)
[英]Value of type `Vec<&str>` cannot be built from `std::iter::Iterator<Item=&&str>`
[英]a collection of type `str` cannot be built from `std::iter::Iterator<Item=char>`
以下代码无法编译
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
s += &v.into_iter().collect();
}
有错误:
error[E0277]: a collection of type `str` cannot be built from an iterator over elements of type `char`
--> src/main.rs:5:25
|
5 | s += &v.into_iter().collect();
| ^^^^^^^ a collection of type `str` cannot be built from `std::iter::Iterator<Item=char>`
|
= help: the trait `std::iter::FromIterator<char>` is not implemented for `str`
然而,这种修改似乎有效:
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
let t: String = v.into_iter().collect();
s += &t;
}
我试图了解原因。 任何提示/解释都会有所帮助。 谢谢。
首先,什么有效:
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
s += &v.into_iter().collect::<String>();
}
其次,让我们探讨一下为什么会这样。 您可以在String
上执行 add-assign +=
,因为它实现了AddAssign
trait :
impl<'_> AddAssign<&'_ str> for String
但前提是右侧是&str
。 因此,在您的第一个示例中, rustc
尝试将char
向量收集到str
。 它不会工作,因为Iterator::collect
的签名:
fn collect<B>(self) -> B
where
B: FromIterator<Self::Item>,
规定迭代器只能收集到实现FromIterator
的容器中。 在所有实现它的类型中,你可以看到str
不是其中之一,但String
是。 这就是您所看到的错误消息。
另一方面,在您的第二个示例和此答案中的代码中, rustc
被特别告知要收集到String
。 由于String
以str
作为目标类型实现了Deref
trait :
impl Deref for String {
type target = str;
}
&String
可以强制为&str
。 编译器现在很高兴。
所以现在您应该能够理解为什么以下看起来很有趣的代码也有效:
fn main() {
use std::borrow::Cow;
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
s += &v.into_iter().collect::<Cow<'_, str>>();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.