首页 > 解决方案 > Rust 返回枚举作为泛型类型

问题描述

我正在尝试创建一个包含节点集合的结构。为了限制类型,这些Node中的每一个都可以保存枚举类型NodeVal的值。

然后,我可以将访问器函数添加到 Container 结构以获取和设置值。但是,get_node_f64, get_node_i64我试图创建一个通用函数来接受实现Num trait.

这似乎不起作用,因为 Node 的 val 属性是 NodeVal 而不是 T。但是,如果我将其设为 T,它将能够是任何类型,这是我想避免的。

有什么方法可以实现我想做的事情,还是我以错误的方式构建它?

use std::collections::HashMap;
use num_traits::Num;

pub enum NodeVal {
    Str(String),
    F64(f64),
    Uint64(u64),
    Int64(i64),
}

pub struct Node {
    id: i32,
    val: NodeVal
}

pub struct Container {
    nodes: HashMap<i32, Node>
}

impl Container {
    pub fn new() -> Self {
        Container {
            nodes: HashMap::new()
        }
    }

    pub fn get_node_str(&self, key: &i32) -> Option<String> {
        match self.nodes.get(key) {
            Some(r) => match &r.val {
                NodeVal::Str(x) => Some(x.to_string()),
                _ => None
            },
            None => None
        }
    }

    // Does not compile
    pub fn get_node_num<T: num_traits::Num>(&self, key: &i32) -> Option<T> {
        match self.nodes.get(key) {
            Some(r) => match &r.val {
                NodeVal::F64(x) | NodeVal::Uint64(x) | NodeVal::Int64(x) => Some(*x),
                _ => None
            },
            None => None
        }
    }
}

标签: rust

解决方案


这似乎不起作用,因为 Node 的 val 属性是 NodeVal 而不是 T。但是,如果我将其设为 T,它将能够是任何类型,这是我想避免的。

我得到的是它不起作用,因为x在您匹配的三个变体中是不同的类型,这对 Rust 没有任何意义,它抱怨xinF64是 an f64xinUint64是 anu64xinInt64i64,因此 * 的类型x没有意义。

您对特征边界的使用也是不正确的,特征边界是调用者指定类型的一种方式,但get_node_num在一秒钟内都没有考虑到这一点。

加上推理没有意义:

但是,如果我将其设为 T,它将能够是任何类型,这是我想避免的。

get_node_num决定返回类型是什么,T完全没用。get_node_num也不能工作,因为你不能在 Rust 中返回“f64 或 u64 或 i64”,除非通过创建一个新的enum来存储这些替代方案。


推荐阅读