从文字创建Vec <string>

时间:2017-03-30 22:01:47

标签: rust

我想做

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的建议做出答案。

我应该如何生成此向量?

2 个答案:

答案 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::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();

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