我不知道如何在结构体上实现干净的数学运算,而不需要复制每个结构体值。
如果你想在结构体上执行数学运算,可以编写以下代码:
use std::ops::*;
struct Num {
i: i32,
}
impl Add for Num {
type Output = Num;
fn add(self, other: Num) -> Num {
Num {
i: self.i + other.i,
}
}
}
(This is a simplified example. An actual example might be doing Vector maths)
这让我们可以编写漂亮的
a + (b / (c * d))
代码。由于借用语义,上述代码与
a + b + a
一样容易出错。一旦使用了a
,它就不能再次使用,因为所有权已经转移到了相关函数(即add
)。解决这个问题的简单方法是为结构体实现
Copy
。#[derive(Copy)]
struct Num {
i: i32,
}
这意味着当传递给
add
的Num
被自动克隆以便能够干净地丢弃它们。但这似乎是低效的!我们不需要这些结构体在各个地方都被复制:它是只读的,我们只需要引用它来创建我们返回的新结构。
这让我想到我们应该基于引用来实现数学运算:
impl<'a> Add for &'a Num {
type Output = Num;
fn add(&'a self, other: &'a Num) -> Num {
Num {
i: self.i + other.i,
}
}
}
现在我们有了数学运算,我们不需要一遍又一遍地克隆数据,但现在我们的数学看起来很丑陋!
a + (b / (c * d))
现在必须是&a + &(&b / &(&c * &d))
。即使你有你的值类型引用(例如let a = &Num { /* ... */ }
),因为add
的返回值仍然是一个Num
,所以这并没有帮助。
是否有一种简洁的方法来实现结构体的操作,使得数学运算看起来干净整洁,同时结构体的值也不会被无处不在地复制?
相关文章:
#[inline(always)]
会改进任何东西吗? - SCdFi32
,还是结构体Num
会更大。也就是说,这种特定的抽象是否是自由的。 - 9000