简洁地初始化一个字符串向量

37

我正在尝试创建一个String向量来测试参数解析(因为这是std::env::args()返回的内容),但是我不知道如何简洁地做到这一点。

我想要的:

let test_args = vec!["-w", "60", "arg"]; // should array of Strings
let expected_results = my_arg_parser(test_args);

显然这不起作用,因为向量中的内容都是&str

使用String::from虽然可行,但不具有可扩展性且不美观 :)

let args = vec![String::from("-w"), String::from("60"), String::from("args")];

我可以对引用进行映射,并返回字符串对象,但这似乎非常冗长:

let args = vec!["-w", "60", "args"].iter().map(|x| x.to_string()).collect::<Vec<String>>();

我应该创建一个辅助函数来进行转换,还是有更简单的方法?

3个回答

37
你可以直接在字面值上使用to_string()方法:
let test_args = vec!["-w".to_string(), "60".to_string(), "arg".to_string()];
否则,编写一个宏来实现这个功能将非常简单:

否则,编写一个宏来实现这个功能将非常简单:

macro_rules! vec_of_strings {
    ($($x:expr),*) => (vec![$($x.to_string()),*]);
}

查看Rust语言的例子


1
谢谢你提供的宏,非常不错!虽然 to_stringString::From 稍微短一些,但使用它是否有任何优势呢? - Nick Tomlin
实际上它是等价的:查看 to_string 实现 https://doc.rust-lang.org/src/collections/up/src/libcollections/string.rs.html#1768-1774 - JDemler

18

JDemler已经提供了一个很好的答案。我有两件额外的事情要说:

首先,除了第一个元素之外,您还可以使用into()而不是to_string()。这样略微更短,也等同于to_string()/String::from()。看起来像这样:

vec!["a".to_string(), "b".into(), "c".into()];

其次,你可能需要重新设计你的参数解析。我假设你不会改变从env::args()获取的String。我想象你当前的函数看起来像这样:

fn parse_args(args: &[String]) -> SomeResult { ... }

但是你可以通过不接受 String 而使用 AsRef<str> 使该函数更加通用化。代码如下:

fn parse_args<T: AsRef<str>>(args: &[T]) -> SomeResult { ... }

在文档中,您可以看到String以及str本身实现了该特质。因此,您可以将&[String]&[&str]传递到您的函数中。是不是很棒?
类似地,如果您想要接受任何可以转换为拥有的String的东西,您可以接受<T: Into<String>>,如果您想返回String&str,则可以使用Cow。您可以在这里这里阅读更多信息。
除此之外:有很多好的CLI-Arg解析器(clap-rsdocopt-rs等),所以您可能不需要编写自己的。

12

我认为Lukas Kalbertodt的答案是最佳方案,即使用泛型来接受任何类似于字符串切片的东西。

不过,你可以稍微简化 map 版本:

  1. 没有必要为初始字符串集分配向量。
  2. 无需使用完整类型(Vec<String>),只需指定集合(Vec<_>)。如果将结果传递给仅接受Vec<String>的函数,则根本不需要任何显式类型;它可以完全被推断出来。
  3. map 中可以使用略短的 s.into()

fn do_stuff_with_args(args: Vec<String>) { println!("{}", args.len()) }

fn main() {
    let args = ["-w", "60", "args"].iter().map(|&s| s.into()).collect();
    do_stuff_with_args(args);
}

1
你甚至可以使用 into_iter.map(str::to_owned) 进一步简化这个过程。 - Remi D

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