如何为结构体的引用实现 Add trait? [英] How do I implement the Add trait for a reference to a struct?

查看:23
本文介绍了如何为结构体的引用实现 Add trait?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个两元素 Vector 结构,我想重载 + 运算符.

I made a two element Vector struct and I want to overload the + operator.

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

I made all my functions and methods take references, rather than values, and I want the + operator to work the same way.

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

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

Depending on which variation I try, I either get lifetime problems or type mismatches. Specifically, the &self argument seems to not get treated as the right type.

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

I have seen examples with template arguments on impl as well as Add, but they just result in different errors.

我发现 如何为不同的 RHS 类型和返回值重载运算符? 但即使我将 use std::ops::Mul; 放在顶部,答案中的代码也不起作用.

I found How can an operator be overloaded for different RHS types and return values? but the code in the answer doesn't work even if I put a use std::ops::Mul; at the top.

我每晚使用 rustc 1.0.0 (ed530d7a3 2015-01-16 22:41:16 +0000)

I am using rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000)

我不会接受你只有两个字段,为什么要使用参考"作为答案;如果我想要一个 100 个元素的结构怎么办?我会接受一个答案,该答案表明即使使用大型结构,我也应该按值传递,如果是这种情况(不过我不认为是这样.)我有兴趣了解结构大小的良好经验法则并通过值与结构传递,但这不是当前的问题.

I won't accept "you only have two fields, why use a reference" as an answer; what if I wanted a 100 element struct? I will accept an answer that demonstrates that even with a large struct I should be passing by value, if that is the case (I don't think it is, though.) I am interested in knowing a good rule of thumb for struct size and passing by value vs struct, but that is not the current question.

推荐答案

你需要在 &Vector 而不是在 Vector 上实现 Add>.

You need to implement Add on &Vector rather than on 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.但是引用和任何其他1一样是类型,因此它们也可以实现特征.在引用类型上实现 trait 时,self 的类型是引用;引用是按值传递的.通常,在 Rust 中按值传递意味着转移所有权,但是当引用按值传递时,它们只是被复制(或者如果它是可变引用,则重新借用/移动),并且不会转移所指对象的所有权(因为引用首先不拥有其所指对象).考虑到所有这些,Add::add(和许多其他运算符)按值获取 self 是有意义的:如果您需要获取操作数的所有权,您可以直接在结构体/枚举上实现Add,如果没有,你可以在引用上实现Add.

In its definition, Add::add always takes self by value. But references are types like any other1, so they can implement traits too. When a trait is implemented on a reference type, the type of self is a reference; the reference is passed by value. Normally, passing by value in Rust implies transferring ownership, but when references are passed by value, they're simply copied (or reborrowed/moved if it's a mutable reference), and that doesn't transfer ownership of the referent (because a reference doesn't own its referent in the first place). Considering all this, it makes sense for Add::add (and many other operators) to take self by value: if you need to take ownership of the operands, you can implement Add on structs/enums directly, and if you don't, you can implement Add on references.

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

Here, self is of type &'a Vector, because that's the type we're implementing Add on.

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

Note that I also specified the RHS type parameter with a different lifetime to emphasize the fact that the lifetimes of the two input parameters are unrelated.

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

1 Actually, reference types are special in that you can implement traits for references to types defined in your crate (i.e. if you're allowed to implement a trait for T, then you're also allowed to implement it for &T). &mut T and Box<T> have the same behavior, but that's not true in general for U<T> where U is not defined in the same crate.

这篇关于如何为结构体的引用实现 Add trait?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆