Day 2:結構體方法(impl)

學習目標

  • impl 區塊定義方法
  • 區分 &self, &mut self, self 方法
  • 使用關聯函式(如 ::new

今日重點

impl 區塊

struct User {
    username: String,
    active: bool,
}

impl User {
    // 關聯函式(沒有 self,用 :: 呼叫,常做建構子)
    fn new(username: String) -> User {
        User { username, active: true }
    }

    // 方法(借用 &self,不修改)
    fn describe(&self) -> String {
        format!("User: {}", self.username)
    }

    // 可變方法(&mut self,修改欄位)
    fn deactivate(&mut self) {
        self.active = false;
    }

    // 取得所有權的 self(少見)
    fn into_name(self) -> String {
        self.username
    }
}

fn main() {
    let mut user = User::new(String::from("john"));
    println!("{}", user.describe());
    user.deactivate();
    println!("Active: {}", user.active);
    let name = user.into_name();
    println!("Got name back: {}", name);
    // 之後不能用 user,因為已被 move
}

三種 self 用法

簽名 意思
fn f(&self) 借用,不改資料
fn f(&mut self) 可變借用,改資料
fn f(self) 取得所有權,會 move

練習

struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 { self.width * self.height }
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width >= other.width && self.height >= other.height
    }
}
1. 實作上述方法並測試。 2. 加一個 scale(&mut self, factor: u32) 方法。 3. 用 println!("{:?}", rect) 前,為 Rectangle 派生 #[derive(Debug)]

自我檢查

  • 知道 impl 區塊怎麼用
  • 會寫 &self / &mut self 方法
  • 知道關聯函式(::new)沒 self

深入連結

  • The Book 第 5 章「Method Syntax」