鍍金池/ 教程/ Java/ 運算符與重載
哲學(xué)家就餐問題
鏈接進階
名詞中英文對照
測試
引用和借用
泛型
方法語法
函數(shù)
不安全代碼
并發(fā)
裝箱語法和模式
注釋
棧和堆
運算符與重載
語法索引
文檔
固有功能
所有權(quán)
循環(huán)
通用函數(shù)調(diào)用語法
不定長類型
<code>const</code> 和 <code>static</code>
迭代器
其他語言中的 Rust
枚舉
詞匯表
If語句
猜猜看
錯誤處理
生命周期
編譯器插件
發(fā)布途徑
閉包
trait 對象
不使用標準庫
關(guān)聯(lián)常量
外部函數(shù)接口(FFI)
類型轉(zhuǎn)換
原生類型
匹配
參考文獻
Rust 編程語言
內(nèi)聯(lián)匯編
條件編譯
選擇你的保證
學(xué)習(xí) Rust
`type`別名
自定義內(nèi)存分配器
屬性
if let
高效 Rust
可變性
語法和語義
模式
基準測試
結(jié)構(gòu)體
變量綁定
語言項
切片模式
<code>Deref</code> 強制多態(tài)
關(guān)聯(lián)類型
裸指針
<code>Borrow</code> 和 <code>AsRef</code>
準備
Rust 開發(fā)版
字符串

運算符與重載

operators-and-overloading.md
commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4

Rust 允許有限形式的運算符重載。特定的運算符可以被重載。要支持一個類型間特定的運算符,你可以實現(xiàn)一個的特定的重載運算符的trait。

例如,+運算符可以通過Add特性重載:

use std::ops::Add;

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 0 };
    let p2 = Point { x: 2, y: 3 };

    let p3 = p1 + p2;

    println!("{:?}", p3);
}

main中,我們可以對我們的兩個Point+號,因為我們已經(jīng)為Point實現(xiàn)了Add<Output=Point>。

有一系列可以這樣被重載的運算符,并且所有與之相關(guān)的trait都在std::ops模塊中。查看它的文檔來獲取完整的列表。

實現(xiàn)這些特性要遵循一個模式。讓我們仔細看看Add

# mod foo {
pub trait Add<RHS = Self> {
    type Output;

    fn add(self, rhs: RHS) -> Self::Output;
}
# }

這里總共涉及到3個類型:你impl Add的類型,RHS,它默認是Self,和Output。對于一個表達式let z = x + y,xSelf類型的,yRHS,而zSelf::Output類型。

# struct Point;
# use std::ops::Add;
impl Add<i32> for Point {
    type Output = f64;

    fn add(self, rhs: i32) -> f64 {
        // add an i32 to a Point and get an f64
# 1.0
    }
}

將允許你這樣做:

let p: Point = // ...
let x: f64 = p + 2i32;

在泛型結(jié)構(gòu)體中使用運算符 trait

現(xiàn)在我們知道了運算符 trait 是如何定義的了,我們可以更通用的定義來自[trait 章節(jié)]()的HasArea trait 和Square結(jié)構(gòu)體:

use std::ops::Mul;

trait HasArea<T> {
    fn area(&self) -> T;
}

struct Square<T> {
    x: T,
    y: T,
    side: T,
}

impl<T> HasArea<T> for Square<T>
        where T: Mul<Output=T> + Copy {
    fn area(&self) -> T {
        self.side * self.side
    }
}

fn main() {
    let s = Square {
        x: 0.0f64,
        y: 0.0f64,
        side: 12.0f64,
    };

    println!("Area of s: {}", s.area());
}

對于HasAreaSquare,我們聲明了一個類型參數(shù)T并取代f64。impl則需要更深入的修改:

impl<T> HasArea<T> for Square<T>
        where T: Mul<Output=T> + Copy { ... }

area方法要求我們可以進行邊的乘法,所以我們聲明的T類型必須實現(xiàn)std::ops::Mul。比如上面提到的AddMul自身獲取一個Output參數(shù):因為我們知道相乘時數(shù)字并不會改變類型,我也設(shè)定它為TT也必須支持拷貝,所以 Rust 并不嘗試將self.side移動進返回值。