繁体   English   中英

不能从 `std::iter::Iterator 构建 `str` 类型的集合<Item=char> `

[英]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 由于Stringstr作为目标类型实现了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM