特性中的默认构造函数实现



PointVec2使用相同的变量和完全相同的构造函数定义:

pub struct Point {
pub x: f32,
pub y: f32,
}
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Point {
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}

是否可以定义一个特性来实现构造函数?

到目前为止,我发现只有在内部变量未知的情况下才能定义接口:

pub trait TwoDimensional {
fn new(x: f32, y: f32) -> Self;
}

您当然可以定义这样一个特性,并为您的2个结构实现它,但您必须编写两次实现。尽管traits可以为函数提供默认实现,但以下内容不起作用:

trait TwoDimensional {
fn new(x: f32, y: f32) -> Self {
Self {
x,
y,
}
}
}

原因很简单。如果您为i32()enum实现此特性,会发生什么?

从根本上讲,特征没有关于实现它们的底层数据结构的信息。Rust不支持OOP,试图强制使用OOP往往会导致代码丑陋、不自然、性能低下。

然而,如果你有一堆结构,并且想要本质上";在不复制/粘贴的情况下多次写入相同的CCD_ 6";,宏可能很有用。这种模式在标准库中很常见,例如,其中有一些函数是为所有整数类型实现的。例如:

macro_rules! impl_constructor {
($name:ty) => {
impl $name {
pub fn new(x: f32, y: f32) -> Self {
Self {
x, y
}
}
}
}
}
impl_constructor!(Point);
impl_constructor!(Vec2);

这些宏在编译时进行扩展,因此如果您执行了无效操作(例如impl_constructor!(i32)(,则会出现编译错误,因为宏扩展将包含i32 { x, y }

就我个人而言,只有当确实有大量类型需要实现时,我才会使用宏。这只是个人偏好,然而,手写和宏生成的impl块在运行时没有区别。

最新更新