【发布时间】:2015-03-16 07:23:11
【问题描述】:
我创建了两个元素 Vector 结构,我想重载 + 运算符。
我让我的所有函数和方法都采用引用而不是值,并且我希望 + 运算符以相同的方式工作。
impl Add for Vector {
fn add(&self, other: &Vector) -> Vector {
Vector {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
根据我尝试的变体,我可能会遇到终身问题或类型不匹配。具体来说,&self 参数似乎没有被视为正确的类型。
我在impl 和Add 上看到了带有模板参数的示例,但它们只会导致不同的错误。
我找到了How can an operator be overloaded for different RHS types and return values?,但即使我在顶部放了use std::ops::Mul;,答案中的代码也不起作用。
我正在使用 rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000)
我不会接受“你只有两个字段,为什么要使用参考”作为答案;如果我想要一个 100 个元素的结构怎么办?我会接受一个答案,证明即使有一个大的结构,我也应该按值传递,如果是这样的话(但我不认为是这样。)我有兴趣了解结构大小的一个好的经验法则并通过值与结构传递,但这不是当前的问题。
【问题讨论】:
-
“如果我想要一个 100 个元素的结构怎么办” - Rust 使用 RVO 等优化,它会在适当的时候自动使用引用和更好的选择。
-
@Shepmaster:RVO 只会影响返回值,我按值返回。您能否指出任何说明大型结构的特征应该按值实现的文档?
-
我所知道的最好的文档是book chapter on returning pointers。但是,我created an example of adding a large struct 并检查了生成的 LLVM(略微清理):
(%struct.Big* sret, %struct.Big*, %struct.Big*)。我不声称自己是 LLVM 专家,但看起来它会自动通过引用获取和返回。 -
文档也提到了返回值,我同意它不应该是一个参考。事实上,文档曾经说过,除非需要,否则不应将指针用于输入参数,但实际上已将其删除。此外,我将您的示例更改为按引用传递,发现它删除了两个分配(
%arg7 = alloca %struct.Big, align 8和%arg8 = alloca %struct.Big, align 8),因此至少对于大型结构来说,引用更好。 -
我应该指出,我对 LLVM 的了解比任何人都少,所以我的解释可能都是湿的。使用引用进行运算符重载的另一个明显缺点是,如果您碰巧没有引用,
let c = (&a) + (&b);会很烦人。
标签: reference rust traits lifetime