如何改进此功能:
use std::{env, process::exit};
fn get_grid() -> [[u8; 9]; 9] {
let mut grid: [[u8; 9]; 9] = Default::default();
let mut args: Vec<String> = env::args().collect();
if args.len() != 10 {
eprintln!("This program need 9 strings of 9 numbers between 0 and 9");
exit(1);
}
args.remove(0);
let _: Vec<_> = args
.iter()
.enumerate()
.map(|(i, arg)| {
let _line: Vec<_> = arg
.split(' ')
.enumerate()
.map(|(j, value)| match value.parse() {
Ok(x) => {
grid[i][j] = x;
x
}
Err(e) => {
eprintln!("Value {} is not a valid integer [{}]", value, e);
exit(1);
}
})
.collect();
})
.collect();
return grid;
}
据我所知,.map()
将在收集时构建一个新的可迭代对象(此处为 Vec
),并返回它。我不需要这个迭代,我只想修改一个外部数组,而不是从这个迭代中构建任何东西。
在 JavaScript 中,有 .map
,还有一个 .forEach
,它在 map
上迭代并且不返回任何内容。 Rust 中是否有任何等效项?
我可能只在 args.iter().enumerate() 中使用 for (index, value)
但我正在寻找一种方法来避免显式循环,如果有的话。
最佳答案
要改变现有的数据结构,使用显式循环是最惯用的方法:
for (i, arg) in args.iter().enumerate() {
for (j, value) in arg.split(' ').enumerate() {
match value.parse() {
Ok(x) => {
grid[i][j] = x;
}
Err(e) => {
eprintln!("Value {} is not a valid integer [{}]", value, e);
exit(1);
}
}
}
}
您可以使用 Iterator::for_each
编写它,但它不太可能被大多数 Rust 开发人员认为“更好”:
args.iter().enumerate().for_each(|(i, arg)| {
arg.split(' ')
.enumerate()
.for_each(|(j, value)| match value.parse() {
Ok(x) => {
grid[i][j] = x;
}
Err(e) => {
eprintln!("Value {} is not a valid integer [{}]", value, e);
exit(1);
}
})
});
无论您使用哪种方式,您绝对不应该收集所有那些您随后丢弃的Vec
。
关于loops - 在 Rust 中是否有与 JavaScript 的 forEach 等效的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54854655/