我有一个带有两个变体的枚举.其中一个变体包含VEC,另一个包含BTreeMap.我希望能够迭代这两个容器.实际上,我喜欢给VEC"消息",这样它的行为就像BTreeMap一样,其值固定为1.设置如下:

pub struct Sketch {
    pub name: String,
    pub hashes: Vec<u64>,
}

pub struct WeightedSketch {
    pub name: String,
    pub hashes: BTreeMap<u64, u32>,
}

pub enum SketchType {
    Unweighted(Sketch),
    Weighted(WeightedSketch),
}

impl SketchType {
    pub fn hashes(&self) -> Iter<u64, u32> {
        match self {
            SketchType::Weighted(sketch) => sketch.hashes.iter(),
            SketchType::Unweighted(sketch) => sketch.hashes.iter().map(|hash| (*hash, 1 as u32)).collect::<BTreeMap<u64, u32>>().iter(), 
        }
    }
}

这没有编译,但更关键的是,似乎不是正确的总体方法.作为一个简单的例子,不管SketchType的变体是什么,我都希望能够执行以下操作:

fn do_work(sketch: &SketchType) -> u64 {
    sketch.values().map(|v| *v as u64).sum()
}

枚举是这里的正确方法吗?我需要以某种方式实现SketchType的Iterator特征吗?

谢谢, 多诺万

推荐答案

这就是你要找的东西吗?

use std::collections::BTreeMap;
use itertools::{Itertools, Either}; // 0.11.0

pub struct Sketch {
    pub name: String,
    pub hashes: Vec<u64>,
}

pub struct WeightedSketch {
    pub name: String,
    pub hashes: BTreeMap<u32, u64>,
}

pub enum SketchType {
    Unweighted(Sketch),
    Weighted(WeightedSketch),
}


impl SketchType {
    /// An iterator through the hash values.
    fn values(&self) -> impl Iterator<Item=u64> + '_ {
        // To reconcile the fact that each branch returns a different type of
        // iterator, we make use of `itertools::Either`, which is designed
        // exactly for that.
        match *self {
            SketchType::Unweighted(ref sketch) => 
                Either::Left(sketch.hashes.iter().cloned()),
            SketchType::Weighted(ref sketch) =>
                Either::Right(sketch.hashes.values().cloned())
        }
    }

    /// Look, `do_work` works!
    fn do_work(&self) -> u64 {
        self.values().sum()
    }
}

Rust相关问答推荐

什么时候铁 rust FFI边界上的panic 是未定义的行为?

捕获FnMut闭包的时间不够长

当T不执行Copy时,如何返回Arc Mutex T后面的值?

不能在一个代码分支中具有不变的自身borrow ,而在另一个代码分支中具有可变的self borrow

如何从ruust中的fig.toml中读取?

习语选项<;T>;到选项<;U>;当T->;U用From定义

减少指示ProgressBar在Rust中的开销

使用 select 处理 SIGINT 和子等待!无阻塞

go 重并堆积MPSC通道消息

Rust typestate 模式:实现多个状态?

在多核嵌入式 Rust 中,我可以使用静态 mut 进行单向数据共享吗?

如何在 Rust 中将枚举变体转换为 u8?

仅当函数写为闭包时才会出现生命周期错误

一个函数调用会产生双重borrow 错误,而另一个则不会

如何将这些测试放在一个单独的文件中?

如何将 Rust 字符串转换为 i8(c_char) 数组?

如何在 Rust 中将 UTF-8 十六进制值转换为 char?

强制特征仅在 Rust 中的给定类型大小上实现

缓存自引用函数导致 Rust

如何从 Rust 函数返回数组而不复制它们?