Sea*_*nka 9 list-comprehension rust
如何将以下 Python(其中读取多个文件并将它们的内容用作字典(以文件名作为键)的值)转换为 Rust?
countries = {region: open("{}.txt".format(region)).read() for region in ["canada", "usa", "mexico"]}
Run Code Online (Sandbox Code Playgroud)
我的尝试如下所示,但我想知道是否可以使用单行惯用的解决方案。
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") };
}
Run Code Online (Sandbox Code Playgroud)
gil*_*lch 17
锈病的迭代器有map/ filter/collect方法,它们是够做任何事Python的内涵可以。您可以在成对的迭代器上创建HashMapwith collect,但collect可以返回各种类型的集合,因此您可能必须指定所需的类型。
例如,
use std::collections::HashMap;
fn main() {
println!(
"{:?}",
(1..5).map(|i| (i + i, i * i)).collect::<HashMap<_, _>>()
);
}
Run Code Online (Sandbox Code Playgroud)
大致相当于Python
use std::collections::HashMap;
fn main() {
println!(
"{:?}",
(1..5).map(|i| (i + i, i * i)).collect::<HashMap<_, _>>()
);
}
Run Code Online (Sandbox Code Playgroud)
但从字面上翻译,它实际上更接近于
print({i+i: i*i for i in range(1, 5)})
Run Code Online (Sandbox Code Playgroud)
并不是说你会在 Python 中这样说。
gil*_*lch 10
Python 的理解只是 for 循环和累加器的糖。Rust 有宏——你可以制作任何你想要的糖。
以这个简单的 Python 示例为例,
print({i+i: i*i for i in range(1, 5)})
Run Code Online (Sandbox Code Playgroud)
您可以轻松地将其重写为循环和累加器:
map = {}
for i in range(1, 5):
map[i+i] = i*i
print(map)
Run Code Online (Sandbox Code Playgroud)
你可以在 Rust 中以同样的方式做到这一点。
use std::collections::HashMap;
fn main() {
let mut hm = HashMap::new();
for i in 1..5 {
hm.insert(i + i, i * i);
}
println!("{:?}", hm);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用宏为您重写此表单。
use std::collections::HashMap;
macro_rules! hashcomp {
($name:ident = $k:expr => $v:expr; for $i:ident in $itr:expr) => {
let mut $name = HashMap::new();
for $i in $itr {
$name.insert($k, $v);
}
};
}
Run Code Online (Sandbox Code Playgroud)
当您使用它时,生成的代码要紧凑得多。并且这种分隔符标记的选择使其类似于 Python。
fn main() {
hashcomp!(hm = i+i => i*i; for i in 1..5);
println!("{:?}", hm);
}
Run Code Online (Sandbox Code Playgroud)
这只是一个可以处理单个循环的基本示例。Python 的推导式也可以有过滤器和额外的循环,但更高级的宏可能也可以做到这一点。
| 归档时间: |
|
| 查看次数: |
6591 次 |
| 最近记录: |