如何翻译下面的Python,其中读取了几个文件,并且它们的内容被用作字典的值(文件名为键),以及Rust?
countries = {region: open("{}.txt".format(region)).read() for region in ["canada", "usa", "mexico"]}
我的尝试如下所示,但我想知道是否可以使用单行,惯用的解决方案 .
use std::{
fs::File,
io::{prelude::*, BufReader},
path::Path,
collections::HashMap,
};
macro_rules! map(
{ $($key:expr => $value:expr),+ } => {
{
let mut m = HashMap::new();
$(
m.insert($key, $value);
)+
m
}
};
);
fn lines_from_file<P>(filename: P) -> Vec<String>
where
P: AsRef<Path>,
{
let file = File::open(filename).expect("no such file");
let buf = BufReader::new(file);
buf.lines()
.map(|l| l.expect("Could not parse line"))
.collect()
}
fn main() {
let _countries = map!{ "canada" => lines_from_file("canada.txt"),
"usa" => lines_from_file("usa.txt"),
"mexico" => lines_from_file("mexico.txt") };
}
2 回答
Rust的迭代器有
map
/filter
/collect
方法,足以完成Python的理解所能做的任何事情 . 您可以在对的迭代器上使用collect
创建HashMap
,但collect
可以返回各种类型的集合,因此您可能必须指定所需的类型 .例如,
大致相当于Python
虽然从概念上讲,它实际上更接近于
Python的理解只是for循环和累加器的糖 . Rust有macros - 你可以制作你想要的任何糖 .
拿这个简单的Python例子,
您可以轻松地将其重写为循环和累加器:
你可以在Rust中以同样的方式完成它 .
您可以使用宏来重写此表单 .
使用它时,生成的代码更紧凑 . 这种分隔符标记的选择使它类似于Python .
这只是一个可以处理单个循环的基本示例 . Python的理解也可以有过滤器和额外的循环,但更高级的宏也可能会这样做 .