我目前正在学习Ruust,我想从拥有字符串的项目向量中收集字符串的引用(&STR).

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();
}

此代码无法编译,出现以下错误:

[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`

can通过调用as_str()来提取字符串片来使其工作:

let names: Vec<&str> = channels.iter().map(|x| x.name.as_str()).collect();

然而,我想了解why这是必需的.根据我的理解,由于德雷夫的胁迫,&String可以转化为&str.为什么我必须明确使用as_str()?此外,在性能方面,取as_str()是否等同于引用一个项?

推荐答案

Deref强制usually的工作方式与您预期的一样,但它取决于类型推断的棘手细节.特别是,在这种情况下,编译器结束闭包返回&String,当它意识到我们需要&str时,已经太晚了(在collect()之后),它不会及时回go 修复它.

提示编译器的方式有多种,而不是as_str():

// Notice the `as _`.
let names: Vec<&str> = channels.iter().map(|x| &x.name as _).collect();
let names: Vec<&str> = channels.iter().map(|x| -> &str { &x.name }).collect();
let names: Vec<&str> = channels.iter().map(|x| &*x.name).collect();

此外,在性能方面,取as_str()是否等同于引用一个项目?

是.它只是显式地做编译器通常隐式做的事情,但这项工作需要以任何一种方式完成.

Rust相关问答推荐

如何在Rust中为具有多个数据持有者的enum变体编写文档 comments ?

空字符串转换为Box字符串时是否分配?<>

将此字符串转换为由空格字符分隔的空格

有没有办法模仿对象安全克隆?

MutexGuard中的过滤载体不需要克隆

如何格式化传入Rust中mysql crate的Pool::new的字符串

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

使用启用优化的 alloc 会导致非法指令崩溃

在 Rust 中查找向量中 dyn struct 的索引

将多维数组转换为切片

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

由特征键控的不同 struct 的集合

Some(v) 和 Some(&v) 有什么区别?

使用 rust 在 google cloud run (docker) 中访问环境变量的适当方法

发生移动是因为 `data` 的类型为 `Vec`,它没有实现 `Copy` 特性

Rust,我如何正确释放堆分配的内存?

通用函数中的生命周期扣除和borrow (通用测试需要)

传递 Option<&mut T> 时何时需要 mut