[英]How do I implement the Add trait for a reference to a struct?
我做了一個兩元素的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
上看到了帶有模板參數的示例,但它們只會導致不同的錯誤。
我發現如何為不同的 RHS 類型和返回值重載運算符? 但是即使我use std::ops::Mul;
答案中的代碼也不起作用use std::ops::Mul;
在頂部。
我每晚使用 rustc 1.0.0 (ed530d7a3 2015-01-16 22:41:16 +0000)
我不會接受“你只有兩個字段,為什么要使用參考”作為答案; 如果我想要一個 100 個元素的結構怎么辦? 我會接受一個答案,該答案表明即使使用大型結構,我也應該按值傳遞,如果是這樣的話(不過我不認為是這樣。)我有興趣了解結構大小的良好經驗法則並通過值與結構傳遞,但這不是當前的問題。
您需要在&Vector
而不是在Vector
上實現Add
。
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
。
在這里, self
是&'a Vector
類型,因為這是我們實現Add
on 的類型。
請注意,我還指定了具有不同生命周期的RHS
類型參數,以強調兩個輸入參數的生命周期無關的事實。
1實際上,引用類型的特殊之處在於您可以為在 crate 中定義的類型的引用實現特征(即,如果您被允許為T
實現一個特征,那么您也可以為&T
實現它)。 &mut T
和Box<T>
具有相同的行為,但對於U<T>
,通常情況並非如此,其中U
未在同一個板條箱中定義。
如果要支持所有場景,必須支持所有組合:
在 rust 中,這是通過內部宏完成的。
幸運的是,有一個Rust crate, impl_ops ,它還提供了一個宏來為我們編寫樣板:這個 crate 提供了impl_op_ex! 宏,它生成所有組合。
這是他們的樣本:
#[macro_use] extern crate impl_ops;
use std::ops;
impl_op_ex!(+ |a: &DonkeyKong, b: &DonkeyKong| -> i32 { a.bananas + b.bananas });
fn main() {
let total_bananas = &DonkeyKong::new(2) + &DonkeyKong::new(4);
assert_eq!(6, total_bananas);
let total_bananas = &DonkeyKong::new(2) + DonkeyKong::new(4);
assert_eq!(6, total_bananas);
let total_bananas = DonkeyKong::new(2) + &DonkeyKong::new(4);
assert_eq!(6, total_bananas);
let total_bananas = DonkeyKong::new(2) + DonkeyKong::new(4);
assert_eq!(6, total_bananas);
}
更好的是,他們有一個impl_op_ex_commutative! 如果您的運算符碰巧是可交換的,這也會生成參數反轉的運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.