我不知道如何在不要求将这些结构值复制到任何地方的情况下对结构进行干净的数学运算。
如果你想拥有一个可以执行数学运算的结构,你会写这样的东西:
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,
}
}
}
(这是一个简化的例子。一个实际的例子可能是做向量数学)
这让我们可以编写漂亮的a + (b / (c * d))
样式代码。
由于借用语义,上述代码以a + b + a
. 一旦a
使用一次就不能再次使用,因为所有权已转移到相关功能(即add
)。
解决这个问题的简单方法是Copy
为结构实现:
#[derive(Copy)]
struct Num {
i: i32,
}
这意味着当Num
s 传递给时add
,它们的值会自动克隆,以便可以干净地删除它们。
但这似乎效率低下!我们不需要在所有地方复制这些结构:它是只读的,我们真的只需要引用它来创建我们要返回的新结构。
这让我认为我们应该在引用上实现数学运算:
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
仍然是 a Num
。
有没有一种干净的方法来实现结构的操作,使得数学运算看起来很干净,并且结构值不会被复制到任何地方?
有关的: