reference - 如何为对结构的引用实现 Add 特性?

标签 reference rust traits lifetime

我制作了一个包含两个元素的 Vector 结构,我想重载 + 运算符。

我让我所有的函数和方法都采用引用,而不是值,我希望 + 运算符以相同的方式工作。

impl Add for Vector {
    fn add(&self, other: &Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

根据我尝试的变体,我要么遇到生命周期问题,要么类型不匹配。具体来说,&self 参数似乎没有被视为正确的类型。

我在 implAdd 上看到过带有模板参数的示例,但它们只会导致不同的错误。

我找到了 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 元素的结构怎么办?我会接受一个答案,该答案表明即使是大型结构,我也应该按值传递,如果是这样的话(不过我不认为是这样。)我有兴趣了解结构大小的良好经验法则以及按值传递还是按结构传递,但这不是当前的问题。

最佳答案

您需要实现 Add&Vector而不是 Vector .

impl<'a, 'b> Add<&'b Vector> for &'a Vector {
    type Output = Vector;

    fn add(self, other: &'b Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

在其定义中,Add::add总是需要 self按值(value)。但是引用是类似于任何其他1 的类型,因此它们也可以实现特征。当在引用类型上实现特征时,self 的类型是引用;引用按值传递。通常,在 Rust 中按值传递意味着转移所有权,但是当按值传递引用时,它们只是被复制(或者如果它是可变引用则重新借用/移动),并且不会转移所指对象的所有权(因为引用一开始并不拥有它的参照物)。考虑到所有这些,Add::add 是有意义的(和许多其他运营商)采取 self按值:如果你需要获得操作数的所有权,你可以实现 Add直接在结构/枚举上,如果你不这样做,你可以实现 Add关于引用。

在这里,self类型为 &'a Vector ,因为那是我们正在实现的类型 Add上。

请注意,我还指定了 RHS具有不同生命周期的类型参数,以强调两个输入参数的生命周期无关的事实。


1 实际上,引用类型的特殊之处在于您可以为在您的 crate 中定义的类型的引用实现特征(即,如果您被允许为 T 实现特征,那么您也允许为 &T 实现它)。 &mut TBox<T>具有相同的行为,但对于 U<T> 通常情况并非如此其中 U未在同一个箱子中定义。

关于reference - 如何为对结构的引用实现 Add 特性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28005134/

相关文章:

function - 在 Rust 中实际需要 move 到函数的情况

php - 如何检查一个类是否使用 PHP 中的特征?

php - 从特征中的重写魔术方法调用父魔术方法

rust - 哈希特征不适用于枚举中的 Rc<RefCell<T>>

reference - 为什么对泛型函数中特征的引用必须实现 `Sized` ?

dll - 为什么 Visual Studio 2015 将 stdole.dll 和 Microsoft.AnalysisServices.AdomdClient.dll 添加到我的项目中?

rust - Rust 中枚举的展平向量

java - 如何在构建时在Gradle中运行控制台命令?

php - 对于这种 PHP 按值调用行为有合理的解释吗?还是 PHP 的错误?

rust - 如何初始化相互引用的结构字段