在safe Rust中可以实现动态类型的链表吗?动态类型链表的含义:
Node(56.7) -> Node("hello") -> Node(77) -> ...
我这样做是作为一种练习,尝试了不同的方法都无济于事,使用特质。因此怀疑在安全生 rust 中这样做的可能性。
qzwqbdag1#
您可以使用Any trait,或者更好地使用另一个对象安全trait,它具有您需要的列表中项目的功能。
Any
enum Node { Nil, Node { value: Box<dyn std::any::Any>, next: Box<Node>, }, } impl std::fmt::Debug for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { Node::Nil => write!(f, "Nil"), Node::Node { value, next } => { if let Some(value) = value.downcast_ref::<f64>() { write!(f, "Node({value}) -> {next:?}") } else if let Some(value) = value.downcast_ref::<i32>() { write!(f, "Node({value}) -> {next:?}") } else if let Some(value) = value.downcast_ref::<&str>() { write!(f, "Node({value:?}) -> {next:?}") } else { write!(f, "Node(<unknown type>) -> {next:?}") } } } } } fn main() { let list = Node::Node { value: Box::new(56.7), next: Box::new(Node::Node { value: Box::new("hello"), next: Box::new(Node::Node { value: Box::new(77), next: Box::new(Node::Nil), }), }), }; dbg!(list); }
将输出类似[src/main.rs:39] list = Node(56.7) -> Node("hello") -> Node(77) -> Nil的内容到stderr。
[src/main.rs:39] list = Node(56.7) -> Node("hello") -> Node(77) -> Nil
Node
Box
downcast*
dyn Any
您可以对每种可能的类型使用枚举:
#[derive(Debug)] enum DynamicType { Float(f64), Int(i32), Str(&'static str), } enum Node { Nil, Node { value: DynamicType, next: Box<Node>, }, } impl std::fmt::Debug for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { Node::Nil => write!(f, "Nil"), Node::Node { value, next } => write!(f, "Node({value:?}) -> {next:?}"), } } } fn main() { use DynamicType::*; let list = Node::Node { value: Float(56.7), next: Box::new(Node::Node { value: Str("hello"), next: Box::new(Node::Node { value: Int(77), next: Box::new(Node::Nil), }), }), }; dbg!(list); }
match
DynamicType
1条答案
按热度按时间qzwqbdag1#
如果你的列表必须使用任何类型
您可以使用
Any
trait,或者更好地使用另一个对象安全trait,它具有您需要的列表中项目的功能。将输出类似
[src/main.rs:39] list = Node(56.7) -> Node("hello") -> Node(77) -> Nil
的内容到stderr。优点
Node
都有两个Box
的大小,无论您将什么类型放入列表。缺点
downcast*
可能很快就会变得非常笨拙,另外,使用dyn Any
也没有什么实际用途。Box
的必要附加间接寻址。如果你知道列表中的类型
您可以对每种可能的类型使用枚举:
优点
match
,并立即知道你在处理什么类型。Node
中。缺点
DynamicType
包含各种大小,您可能最终会在Node
上浪费大量空间。