23·面向对象进阶

运算符重载

运算符重载

学习目标

  1. 通过 trait 重载运算符
  2. 掌握常用运算符 trait
  3. 实现自定义类型的运算

核心概念

标准库运算符 Trait

use std::ops::{Add, Sub, Mul, Neg};

#[derive(Debug, Clone, Copy)]
struct Vector2D {
    x: f64,
    y: f64,
}

impl Add for Vector2D {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Vector2D { x: self.x + other.x, y: self.y + other.y }
    }
}

impl Sub for Vector2D {
    type Output = Self;
    fn sub(self, other: Self) -> Self {
        Vector2D { x: self.x - other.x, y: self.y - other.y }
    }
}

impl Mul<f64> for Vector2D {
    type Output = Self;
    fn mul(self, scalar: f64) -> Self {
        Vector2D { x: self.x * scalar, y: self.y * scalar }
    }
}

impl Neg for Vector2D {
    type Output = Self;
    fn neg(self) -> Self {
        Vector2D { x: -self.x, y: -self.y }
    }
}

fn main() {
    let a = Vector2D { x: 1.0, y: 2.0 };
    let b = Vector2D { x: 3.0, y: 4.0 };

    println!("a + b = {:?}", a + b);
    println!("a - b = {:?}", a - b);
    println!("a * 2 = {:?}", a * 2.0);
    println!("-a = {:?}", -a);
}

Display trait

use std::fmt;

struct Color {
    r: u8,
    g: u8,
    b: u8,
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
    }
}

impl fmt::Debug for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Color(r={}, g={}, b={})", self.r, self.g, self.b)
    }
}

fn main() {
    let red = Color { r: 255, g: 0, b: 0 };
    println!("Display: {}", red);
    println!("Debug: {:?}", red);
}

Index 和 IndexMut

use std::ops::{Index, IndexMut};

struct Matrix {
    data: Vec<Vec<f64>>,
    rows: usize,
    cols: usize,
}

impl Matrix {
    fn new(rows: usize, cols: usize) -> Self {
        Matrix {
            data: vec![vec![0.0; cols]; rows],
            rows,
            cols,
        }
    }
}

impl Index<usize> for Matrix {
    type Output = Vec<f64>;
    fn index(&self, row: usize) -> &Vec<f64> {
        &self.data[row]
    }
}

impl IndexMut<usize> for Matrix {
    fn index_mut(&mut self, row: usize) -> &mut Vec<f64> {
        &mut self.data[row]
    }
}

fn main() {
    let mut m = Matrix::new(3, 3);
    m[0][0] = 1.0;
    m[1][1] = 2.0;
    m[2][2] = 3.0;
    println!("m[1][1] = {}", m[1][1]);
}

Deref trait

use std::ops::Deref;

struct MyString {
    data: String,
}

impl Deref for MyString {
    type Target = str;
    fn deref(&self) -> &str {
        &self.data
    }
}

fn greet(name: &str) {
    println!("Hello, {}!", name);
}

fn main() {
    let s = MyString { data: String::from("Rust") };
    greet(&s);  // Deref 强制转换:MyString → &str
}

实践练习

练习 1:复数运算

use std::ops::{Add, Mul};
use std::fmt;

#[derive(Clone, Copy)]
struct Complex {
    real: f64,
    imag: f64,
}

impl Complex {
    fn new(real: f64, imag: f64) -> Self {
        Complex { real, imag }
    }
}

impl Add for Complex {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Complex {
            real: self.real + other.real,
            imag: self.imag + other.imag,
        }
    }
}

impl Mul for Complex {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        Complex {
            real: self.real * other.real - self.imag * other.imag,
            imag: self.real * other.imag + self.imag * other.real,
        }
    }
}

impl fmt::Display for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} + {}i", self.real, self.imag)
    }
}

fn main() {
    let a = Complex::new(1.0, 2.0);
    let b = Complex::new(3.0, 4.0);
    println!("{} + {} = {}", a, b, a + b);
    println!("{} × {} = {}", a, b, a * b);
}

常见错误

1. 忘记关联类型

// ❌ 缺少 Output
// impl Add for MyType {
//     fn add(self, other: Self) -> Self { ... }
// }

// ✅
// impl Add for MyType {
//     type Output = Self;
//     fn add(self, other: Self) -> Self { ... }
// }

小结

Trait运算符
Add+
Sub-
Mul*
Div/
Neg一元 -
Index[]
Display{}
Debug{:?}
Deref自动解引用

练习编辑器

rust
Loading...