Rust可以讓我們對某些運(yùn)算符進(jìn)行重載,這其中大部分的重載都是對std::ops
下的trait進(jìn)行重載而實(shí)現(xiàn)的。
我們現(xiàn)在來實(shí)現(xiàn)一個只支持加法的閹割版復(fù)數(shù):
use std::ops::Add;
#[derive(Debug)]
struct Complex {
a: f64,
b: f64,
}
impl Add for Complex {
type Output = Complex;
fn add(self, other: Complex) -> Complex {
Complex {a: self.a+other.a, b: self.b+other.b}
}
}
fn main() {
let cp1 = Complex{a: 1f64, b: 2.0};
let cp2 = Complex{a: 5.0, b:8.1};
let cp3 = cp1 + cp2;
print!("{:?}", cp3);
}
輸出:
Complex { a: 6, b: 10.1}
這里我們實(shí)現(xiàn)了std::ops::Add
這個trait。這時候有同學(xué)一拍腦門,原來如此,沒錯……其實(shí)Rust的大部分運(yùn)算符都是std::ops
下的trait的語法糖!
我們來看看std::ops::Add
的具體結(jié)構(gòu)
impl Add<i32> for Point {
type Output = f64;
fn add(self, rhs: i32) -> f64 {
// add an i32 to a Point and get an f64
}
}
有的同學(xué)會問了,這個Output
是腫么回事?答,類型轉(zhuǎn)換喲親!
舉個不太恰當(dāng)?shù)睦踝?,我們在現(xiàn)實(shí)中會出現(xiàn)0.5+0.5=1
這樣的算式,用Rust的語言來描述就是: 兩個f32
相加得到了一個i8
。顯而易見,Output就是為這種情況設(shè)計的。
還是看代碼:
use std::ops::Add;
#[derive(Debug)]
struct Complex {
a: f64,
b: f64,
}
impl Add for Complex {
type Output = Complex;
fn add(self, other: Complex) -> Complex {
Complex {a: self.a+other.a, b: self.b+other.b}
}
}
impl Add<i32> for Complex {
type Output = f64;
fn add(self, other: i32) -> f64 {
self.a + self.b + (other as f64)
}
}
fn main() {
let cp1 = Complex{a: 1f64, b: 2.0};
let cp2 = Complex{a: 5.0, b:8.1};
let cp3 = Complex{a: 9.0, b:20.0};
let complex_add_result = cp1 + cp2;
print!("{:?}\n", complex_add_result);
print!("{:?}", cp3 + 10i32);
}
輸出結(jié)果:
Complex { a: 6, b: 10.1 }
39
Rust的運(yùn)算符是基于trait系統(tǒng)的,同樣的,運(yùn)算符可以被當(dāng)成一種對范型的限制,我們可以這么要求范型T必須實(shí)現(xiàn)了trait Mul<Output=T>
。
于是,我們得到了如下的一份代碼:
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());
}
對于trait HasArea<T>
和 struct Square<T>
,我們通過where T: Mul<Output=T> + Copy
限制了T
必須實(shí)現(xiàn)乘法。同時Copy則限制了Rust不再將self.side給move到返回值里去。
寫法簡單,輕松愉快。