使用enum Axes限制CoordinateQuaternion:

#[derive(Clone)]
pub enum Axes {
    Coordinate {
        x: f64,
        y: f64,
        z: f64,
        reserve: Vec<f64>,
    },
    Quaternion {
        x: f64,
        y: f64,
        z: f64,
    },
}

impl Axes {
    pub fn shift(&mut self, Sample: &Axes) -> () {
        let Dup: Axes = self.clone();
        match Dup {
            Axes::Coordinate { x, y, z, reserve } => match &Sample {
                Axes::Coordinate { x, y, z, reserve } => {
                    *self = Axes::Coordinate {
                        x: *x,
                        y: *y,
                        z: *z,
                        reserve: reserve.to_vec(),
                    };
                }
                _ => panic!(),
            },
            Axes::Quaternion { x, y, z } => match &Sample {
                Axes::Quaternion { x, y, z } => {
                    *self = Axes::Quaternion {
                        x: *x,
                        y: *y,
                        z: *z,
                    };
                }
                _ => panic!(),
            },
        }
    }
}

使用trait Axes链接CoordinateQuaternion struct :

pub trait Axes {
    fn shift(&mut self, Sample: &Axes) -> ();
    fn fold(&mut self, Sample: &Axes) -> ();
}

pub struct Coordinate {
    pub x: f64,
    pub y: f64,
    pub z: f64,
    pub reserve: Vec<f64>,
}

pub struct Quaternion {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl Axes for Coordinate {
    fn shift(&mut self, Sample: &Axes) -> () {}
    fn fold(&mut self, Sample: &Axes) -> () {}
}

impl Axes for Quaternion {
    fn shift(&mut self, Sample: &Axes) -> () {}
    fn fold(&mut self, Sample: &Axes) -> () {}
}

在这种情况下,在 struct 上实现的特征是否更容易访问、更高效?我不知道该使用哪种,在什么情况下使用.

推荐答案

针对您的情况使用traits和enum之间的一个重大区别是它们的可扩展性.如果将Axes设为枚举,则这两个选项将硬编码到类型中.如果你想添加第三种形式的axis,你必须修改类型本身,这可能会涉及对使用Axes的代码的大量修改(例如,你在Axes上匹配的任何地方都可能需要更改).另一方面,如果你把Axes作为一个特征,你可以通过定义一个新类型并编写一个合适的实现来添加其他类型的轴,而不需要修改现有的代码.这甚至可以从库外完成,例如由用户完成.

另一个重要的考虑因素是对 struct 的内部 struct 需要多少访问.使用枚举,可以完全访问存储在 struct 中的所有数据.如果你想写一个函数,它可以使用一个trait在CoordinateQuaternion上运行,那么你只能执行Axes trait中描述的那些操作(在本例中是ShiftFold).例如,如果给出了Axes的实现,则无法通过Axes接口简单地检索(X,Y,Z)元组.如果你需要在某个时候这样做,你必须添加一个新的方法.

如果不知道如何使用这些类型,很难确定这些选项中的哪一个是更好的 Select ,但如果是我,我可能会使用枚举.归根结底,这在很大程度上取决于偏好,但希望这能让你在做决定时对需要考虑的事情有所了解.

Rust相关问答推荐

将此字符串转换为由空格字符分隔的空格

无法理解铁 rust &S错误处理

在UdpSocket上使用sendto时的隐式套接字绑定

如何导入crate-type=[";cdylib;]库?

避免在Collect()上进行涡鱼类型的涂抹,以产生<;Vec<;_>;,_>;

如果变量本身不是None,如何返回;如果没有,则返回None&Quot;?

将特征与具有生命周期的关联类型一起使用时的生命周期方差问题

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

我可以禁用发布模式的开发依赖功能吗?

通过mem::transmute将数组展平安全吗?

decltype、dyn、impl traits,重构时如何声明函数的返回类型

Rust 编译器不统一在 if let 表达式的分支中都 impl Future 的类型

从 HashMap>, _> 中删除的生命周期问题

了解 Rust 闭包:为什么它们持续持有可变引用?

在每个循环迭代中删除borrow

是否有适当的方法在参考 1D 中转换 2D 数组

为什么可以从闭包中返回私有 struct

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

如果返回类型是通用的,我可以返回 &str 输入的一部分吗?

为什么 Rust 标准库同时为 Thing 和 &Thing 实现特征?