Nạp chồng toán tử (Operator Overloading)

Ta có thể thực hiện overloading toán tử thông qua các trait trong std::ops:

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

impl std::ops::Add for Point {
    type Output = Self;

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

fn main() {
    let p1 = Point { x: 10, y: 20 };
    let p2 = Point { x: 100, y: 200 };
    println!("{:?} + {:?} = {:?}", p1, p2, p1 + p2);
}
This slide should take about 10 minutes.

Một số điểm cần thảo luận:

  • Ta có thể implement Add cho &Point. Việc này có ích trong những tình huống nào?
    • Trả lời: Add:add tiêu thụ self. Nếu kiểu T mà ta muốn overloading toán tử không implement Copy, ta cũng nên cân nhắc overload toán tử cho &T. Như vậy ta có thể tránh việc clone không cần thiết tại thời điểm gọi hàm.
  • Tại sao Output là một associated type? Có thể thay thế Output bằng một tham số generic cho hàm không?
    • Trả lời: Tham số generic của hàm được quyết định bởi người gọi hàm, nhưng associated types (như Output) được quyết định bởi người implement trait.
  • Ta có thể implement Add cho hai kiểu dữ liệu khác nhau, ví dụ impl Add<(i32, i32)> for Point sẽ cộng một tuple vào một Point.