Atualmente estou aprendendo sobre ferrugem e gostaria de coletar uma referência de strings (&strs) de um vetor de itens que possuem uma String.
struct Channel {
cid: usize,
name: String,
}
fn main() {
let channels: Vec<Channel> = vec![Channel {
cid: 1,
name: "Hello".to_string(),
}];
let names: Vec<&str> = channels.iter().map(|x| &x.name).collect();
}
Este código não compila, dando este erro:
[E0277]: a value of type `Vec<&str>` cannot be built from an iterator over elements of type `&String`
--> src/main.rs:11:61
|
11 | let names: Vec<&str> = channels.iter().map(|x| &x.name).collect();
| ^^^^^^^ value of type `Vec<&str>` cannot be built from `std::iter::Iterator<Item=&String>`
|
= help: the trait `FromIterator<&String>` is not implemented for `Vec<&str>`
= help: the trait `FromIterator<&str>` is implemented for `Vec<&str>`
= help: for that trait implementation, expected `str`, found `String`
note: the method call chain might not have had the expected associated types
--> src/main.rs:11:44
|
7 | let channels: Vec<Channel> = vec![Channel {
| __________________________________-
8 | | cid: 1,
9 | | name: "Hello".to_string(),
10 | | }];
| |______- this expression has type `Vec<Channel>`
11 | let names: Vec<&str> = channels.iter().map(|x| &x.name).collect();
| ------ ^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `&String` here
| |
| `Iterator::Item` is `&Channel` here
note: required by a bound in `collect`
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2050:19
|
2050 | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
Posso fazê -lo funcionar chamando as_str() para extrair a fatia da string:
let names: Vec<&str> = channels.iter().map(|x| x.name.as_str()).collect();
No entanto, gostaria de entender por que isso é necessário. Pelo que entendi, devido à coerção deref, a &String
pode ser convertido em a &str
. Por que preciso usar explicitamente as_str()
? Além disso, em termos de desempenho, tomar é as_str()
o mesmo que fazer referência a um item?