Point
和Vec2
使用相同的变量和完全相同的构造函数定义:
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
块在运行时没有区别。