我想做
fn main() {
let options: Vec<String> = vec!["a", "b", "c"].map(|s| s.to_owned()).collect();
}
因为这似乎是获取拥有String
s的向量的最简单方法,但是我遇到了这个错误:
error: no method named `map` found for type `std::vec::Vec<&str>` in the current scope
...
note: the method `map` exists but the following trait bounds were not satisfied:
`std::vec::Vec<&str> : std::iter::Iterator`, `[&str] : std::iter::Iterator`
我不知道[&str] : std::iter::Iterator
绑定的必要性来自哪里。如果您忽略了split_whitespace
部分,我基本上会按照this question的建议做出答案。
我应该如何生成此向量?
答案 0 :(得分:3)
如果忽略
的部分split_whitespace
是的,除了你不能忽视这一部分。 The docs for split_whitespace
州(强调我的):
迭代器返回
split_whitespace
会在以空格分隔的字符串片段上返回iterator,并map
is a method on Iterator
。
Vec
不是迭代器。您可以看到Vec
没有实现它自己的map
方法:
找不到类型
的名为map
std::vec::Vec<&str>
的方法
编译器试图建议你可能的意思,但还没有完成:
注意:方法
map
存在,但不满足以下特征界限:
您可以通过致电Vec::iter
或into_iter
从Vec
获取迭代器:
fn main() {
let options: Vec<String> = vec!["a", "b", "c"].into_iter().map(|s| s.to_owned()).collect();
}
但是,这里不需要分配两个向量,数组和向量更有效:
let options: Vec<_> = ["a", "b", "c"].iter().map(|s| s.to_string()).collect();
iterator over a slice将引用(&T
)返回到切片中的元素。由于每个元素已经是&str
,因此s
的类型为&&str
。在引用引用上调用to_owned
只需克隆引用。您也可以说.map(|&s| s.to_owned())
,其中取消引用值一次,生成&str
。在to_owned
上拨打&str
会分配String
。
答案 1 :(得分:2)
如果我不得不重复创建String
s的向量,我会使用宏:
macro_rules! vec_of_strings {
// match a list of expressions separated by comma:
($($str:expr),*) => ({
// create a Vec with this list of expressions,
// calling String::from on each:
vec![$(String::from($str),)*] as Vec<String>
});
}
fn main() {
let v1 = vec_of_strings![];
let v2 = vec_of_strings!["hello", "world", "!"];
println!("{:?}", v1);
println!("{:?}", v2);
}
输出:
[]
["hello", "world", "!"]