如何将Vec<String>转换为&[&str]?

3

我之前经常使用Vec<&str>,但是在Discord上有人说服我改用&[&str],但是在某些情况下这会产生问题。例如,以下代码曾经可以正常工作:

fn main() { 
  let pos: Vec<String> = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()];
  let pos: Vec<&str> = pos.iter().map(AsRef::as_ref).collect(); 
}

当我将第二行改为:
let pos: &[&str] = pos.iter().map(AsRef::as_ref).collect(); 

我收到了错误提示:

error[E0277]: a value of type `&[&str]` cannot be built from an iterator over elements of type `&_`
 --> bin/seq.rs:3:51
  |
3 |     let pos: &[&str] = pos.iter().map(AsRef::as_ref).collect();    
  |                                                      ^^^^^^^ value of type `&[&str]` cannot be built from `std::iter::Iterator<Item=&_>`
  |
  = help: the trait `FromIterator<&_>` is not implemented for `&[&str]`

我该如何将一个Vec<String>转换为&[&str]。我从StackOverflow上的这个答案中得到了这个方法,但我试图将其移植到&[&str]上并没有成功。

你可以轻松地将 &Vec<T> 用作 &[T],因为它有一个解引用强制转换,但你需要使用 .collect() 转换成 Vec - kmdreko
1
你收到的建议听起来像是随意给出或接受的,可能类似于这样的推理?为什么不建议将 String (&String)、Vec (&Vec) 或 Box (&Box) 的引用作为函数参数? - kmdreko
你好,这段代码可以在两个时间点运行:“let pos: Vec<&str> = pos.iter().map(AsRef::as_ref).collect();”和“let s: &[&str] = pos.as_slice();”。但是,也许存在更好的解决方案。 - Zeppi
@ÖmerErden 我只是想回复你,我在诊断中记录了这个错误,它来自于你的语法(因为我认为这也是有问题的)https://github.com/rust-lang/rust/issues/89805 - Evan Carroll
1
请查看as_slice,它做的是同样的事情(playground)。至于Github问题,请小心,那段代码不正确,你在获取切片时缺少了& - Ömer Erden
显示剩余3条评论
1个回答

6
一种简单的方法是使用 .as_slice()
let pos: Vec<String> = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()];
let pos: Vec<&str> = pos.iter().map(AsRef::as_ref).collect();

let pos: &[&str] = pos.as_slice();

但是,也许存在更好的解决方案。



非常好的答案,非常感谢!如果有人有更好的答案,我会接受它,但这个对我很有效。 - Evan Carroll
关于GitHub上的另一种方案: "let pos:& [ & str ] = pos.iter().map(AsRef::as_ref).collect::<Vec<_>>().as_slice();"。这个编译可以通过,但是实际运行时会出现问题。如果您尝试使用pos,例如“dbg!(pos)”,则会收到“error[E0716]: temporary value dropped while borrowed”的错误提示。 - Zeppi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接