我试图将Vec<&str>
转换为Vec<u16>
,但我无法找到一种功能性的方法来实现它。
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
我需要将bar
存入一个Vec<u16>
中。
我试图将Vec<&str>
转换为Vec<u16>
,但我无法找到一种功能性的方法来实现它。
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
我需要将bar
存入一个Vec<u16>
中。
有一个迭代器适配器map
!你可以这样使用它:
let bar: Vec<u16> = foo.split(",").map(|x| x.parse::<u16>().unwrap()).collect();
parse
是一个依赖于特质 FromStr
的库函数,它可能会返回一个错误,因此我们需要 unwrap()
错误类型。(这对于一个简短的例子来说是一个好主意,但在实际代码中,您将希望正确处理错误——如果那里有一个不是 u16
的值,您的程序将会崩溃)。
map
接受一个通过值传递它的参数并返回通过 惰性 应用该函数获得的迭代器的闭包。你正在collect
所有值,但如果你只take(5)
其中的五个,你只会解析五个字符串。
parse
从字符串中解析数字时,可能会失败。这就是为什么函数返回Result
的原因:fn parse<F>(&self) -> Result<F, F::Err>
where
F: FromStr,
iter
获取迭代器,使用 map
更改每个项目,最终使用 collect
返回一个Result
。如果解析成功,则返回Ok
。如果任何一个失败,则返回Err
。fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Result<Vec<u16>, _> = strings.iter().map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
或者您可以通过使用 flat_map
过滤掉 Err
值来移除失败的转换:
fn main() {
let input = "1,2,3";
let strings: Vec<_> = input.split(",").collect();
let numbers: Vec<u16> = strings.iter().flat_map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
fn main() {
let input = "1,2,3";
let numbers: Result<Vec<u16>, _> = input.split(",").map(|x| x.parse()).collect();
println!("{:?}", numbers);
}
另请参阅:
作为一个对Rust不是很有经验的人,我的看法如下。
fn main() {
let foo: &str = "1,2,3"; // Parsing a string here
let bar: Vec<&str> = foo.split(",").collect(); // Bar is a nice vector of &str's
// here the magic happens
let baz = bar.iter().map(|x| x.parse::<i64>());
for x in baz {
match x {
Ok(i) => println!("{}", i),
Err(_) => println!("parse failed"),
}
}
}
parse
返回一个Result
,因此您需要从每个解析的元素中提取值。您可能希望以不同的方式行事,例如仅过滤成功的结果。