我想做
fn main() {
let options: Vec<String> = vec!["a", "b", "c"].map(|s| s.to_owned()).collect();
}
因为这似乎是获取拥有String
向量的最简单方法,但我遇到了此错误:
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
的部分,我基本上是在做这个问题的答案所建议的。
我应该如何生成此向量?
如果您忽略带有
split_whitespace
的部分
是的,除了你不能忽略这部分。split_whitespace
状态的文档(强调我的):
迭代器返回
split_whitespace
返回一个迭代器,迭代器覆盖由空格分隔的字符串片段,map
是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();
切片上的迭代器返回对切片中元素的引用(&T
)。由于每个元素已经是一个&str
,s
的类型是一个&&str
。对引用的引用调用to_owned
只是克隆引用。你也可以说.map(|&s| s.to_owned())
,这会取消引用一次值,产生&str
。在&str
上调用to_owned
将分配一个String
。
如果我必须重复创建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", "!"]