从文字创建 Vec<String>



我想做

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返回一个迭代器,迭代器覆盖由空格分隔的字符串片段,mapIterator上的方法。

Vec不是迭代器。您可以看到Vec没有实现自己的map方法:

找不到map类型std::vec::Vec<&str>的命名方法

编译器试图建议你可能的意思,但并没有完全实现:

注意:该方法map存在,但不满足以下特征边界:

您可以通过调用Vec::iterinto_iterVec获取迭代器:

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)。由于每个元素已经是一个&strs的类型是一个&&str。对引用的引用调用to_owned只是克隆引用。你也可以说.map(|&s| s.to_owned()),这会取消引用一次值,产生&str。在&str上调用to_owned将分配一个String

如果我必须重复创建Strings 的向量,我会使用宏:

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", "!"]

相关内容

最新更新