我正在尝试创建一个String
s的向量来测试arg解析(因为这是std::env::args()
返回的内容)但是如何简洁地解决这个问题。
我想要的是什么:
let test_args = vec!["-w", "60", "arg"]; // should array of Strings
let expected_results = my_arg_parser(test_args);
这显然不起作用,因为向量内容都是&str
s。
使用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>>();
我应该创建一个辅助函数来进行转换,还是有更简单的方法?
答案 0 :(得分:9)
您可以直接在文字上使用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()),*]);
}
答案 1 :(得分:6)
JDemler已经提供了一个很好的答案。我还有两件事要说:
首先,除第一个元素外,您还可以使用into()
代替to_string()
。这略短,也相当于to_string()
/ String::from()
。看起来像这样:
vec!["a".to_string(), "b".into(), "c".into()];
其次,您可能想重新设计arg解析。我将在此假设您不会改变String
来自env::args()
的{{1}}。我想你当前的功能看起来像:
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
或{ {1}},您可以使用Cow
。您可以详细了解here和here。
答案 2 :(得分:4)
我同意Lukas Kalbertodt's answer是最好用的泛型来接受任何看起来像一串字符串的东西。
但是,您可以稍微清理map
版本:
Vec<String>
);你只能指定集合(Vec<_>
)。如果将结果传递给只接受Vec<String>
的函数,则根本不需要任何显式类型;它可以完全推断出来。s.into()
中使用稍短的map
。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);
}