我确信有更好的方法来做到这一点,但我不知道如何在reduce()期间从Enum中提取结构。假设所有枚举在向量中都是相同的(但如果这也不成立,则问题解决方案需要处理)。
最简单的例子:
#[derive(Debug)]
struct Data {
d: u64,
}
#[derive(Debug)]
enum DataEnum {
First(Data),
Second,
}
fn main() {
let v = vec![DataEnum::First(Data{d: 10}), DataEnum::First(Data{d: 5}), DataEnum::First(Data{d: 15}), DataEnum::First(Data{d: 13})];
let mut vi = v.iter();
let mut current = vi.next().unwrap();
let mut max: u64;
match current {
DataEnum::First(data) => max = data.d,
_ => panic!("dont know what to do with {:?}", current),
}
for next in vi {
match next {
DataEnum::First(data) => if max < data.d {
current = next;
max = data.d;
},
_ => panic!("dont know what to do with {:?}", next),
}
}
println!("found max: {:?}", current);
}
有没有更好的方法通过折叠或减少来做到这一点?
我遇到的reduce()问题是我不知道如何正确处理闭包内的“匹配”部分(以提取和比较data.d)。
您当然可以在此类代码中使用
reduce()
。我们首先创建一个实用函数,用于检索与比较相关的数据,我们称之为 key
:
fn key(e: &DataEnum) -> u64 {
match e {
DataEnum::First(data) => data.d,
_ => panic!("dont know what to do with {:?}", e),
}
}
该函数返回
u64
,但它可以返回一个元组或类似的(这是您用来正确支持集合中的异构枚举的)。有了这个功能,你就可以像这样使用 reduce
:
let max = v
.iter()
.reduce(|max, e| if key(e) > key(max) { e } else { max })
.unwrap();
println!("found max: {:?}", max);
然而,Rust 已经提供了一个迭代器方法,通过应用一个键来确定其最大值,方便地称为
max_by_key
,所以你可以使用它:
let max = v.iter().max_by_key(|e| key(e)).unwrap();