我正在尝试创建一个包含节点集合的结构体。为了限制类型,这些节点中的每一个都可以包含枚举类型NodeVal的值。
然后我可以向容器结构体添加访问器函数来获取和设置值。但是,我并没有添加get_node_f64, get_node_i64
等,而是尝试创建一个泛型函数,它接受实现Num trait
的类型。
这似乎不起作用,因为Node的瓦尔属性是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
}
}
}
1条答案
按热度按时间yrwegjxp1#
这似乎不起作用,因为Node的瓦尔属性是NodeVal而不是T。但是,如果我将其设置为T,它将能够是任何类型,这是我希望避免的。
我得到的结果是它不起作用,因为
x
在您要匹配的三个变体中属于不同的类型,这对Rust来说没有任何意义,它抱怨F64
中的x
是f64
,Uint64
中的x
是u64
,Int64
中的x
是i64
,因此x
的类型没有意义(它有三个不兼容的类型,无法协调)。你对trait bounds的使用也是不正确的,trait bounds是 caller 指定类型的一种方式,但是
get_node_num
一秒钟也不考虑,它不关心调用者想要什么。再加上这个推理说不通:
然而,如果我使它T它将能够是任何类型,我想避免。
get_node_num
决定了返回类型是什么,T
是完全无用的。get_node_num
也不能工作,因为你不能在Rust中返回“f64或u64或i64”,除非创建一个新的enum
来存储这些替代项。