The following code fails to compile
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
s += &v.into_iter().collect();
}
with the error:
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`
However this modification seems to work:
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
let t: String = v.into_iter().collect();
s += &t;
}
I am trying to understand the reason. Any hints/explanation would help. Thanks.
Firstly, what works:
fn main() {
let n = 10;
let mut s = String::new();
let v = vec!['a'; n];
s += &v.into_iter().collect::<String>();
}
Secondly, let's explore why that works. You can do add-assign +=
on String
because it implements AddAssign
trait:
impl<'_> AddAssign<&'_ str> for String
but only if the right-hand-side is a &str
. So in your first example, rustc
tries to collect a vector of char
into str
. It won't work because the signature of Iterator::collect
:
fn collect<B>(self) -> B
where
B: FromIterator<Self::Item>,
dictates that an iterator can only be collected into a container which implements FromIterator
. Among all types that do implement it, you can see str
is not one of them, but String
is. That's the error message you've witnessed.
On the other hand, in your second example and the code in this answer, rustc
is specifically told to collect into a String
. And since String
implements Deref
trait with str
as the target type:
impl Deref for String {
type target = str;
}
a &String
can be coerced to &str
. The compiler is now happy.
So now you should be able to decipher why the following funny looking code also works:
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>>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With