實作結構體和列舉

從這裡開始你可以給予你的結構體和列舉一些真正的威力。要對 structenum 呼叫的函式,要寫在 impl 區塊。這些函式被稱為方法(method)impl 區塊中的方法有兩類。

  • 方法:這些方法會取用 self(或是 &self&mut self)。正規方法使用"."(英文句號)。.clone() 是一個正規方法的例子。
  • 關聯函式(associated function, 在某些語言中被稱為"靜態(static)"方法):這些函式不使用 self。關聯的意思是"有相關的"。它們的書寫方式不同,用的是 ::String::from() 是一個關聯函式,Vec::new() 也是。你看到的關聯函式最常被用來建立新變數。

我們將在我們的範例中建立 Animal 並印出它們。

對於新的 structenum,如果你想使用 {:?} 印出來,你需要給它Debug,我們也將會這樣做。如果你在結構體或列舉上面寫了 #[derive(Debug)],那麼你就可以用 {:?} 印出來。這些帶有 #[] 的訊息被稱為屬性(attributes)。你有時可以用它們來告訴編譯器給你的結構體像是 Debug 的能力。屬性有很多種,我們以後會學到。但是 derive 可能是最常見的,你經常在結構體和列舉上面看到它。

#[derive(Debug)]
struct Animal {
    age: u8,
    animal_type: AnimalType,
}

#[derive(Debug)]
enum AnimalType {
    Cat,
    Dog,
}

impl Animal {
    fn new() -> Self {
        // Self 指的是 Animal。
        // 你也可以寫 Animal 而非 Self

        Self {
            // 當我們寫 Animal::new() 我們永遠會得到10歲的貓
            age: 10,
            animal_type: AnimalType::Cat,
        }
    }

    fn change_to_dog(&mut self) { // 因為我們在Animal裡, &mut self 指的是 &mut Animal
                                  // 用 .change_to_dog() 把貓改成狗
                                  // 有了 &mut self 我們就能更改
        println!("Changing animal to dog!");
        self.animal_type = AnimalType::Dog;
    }

    fn change_to_cat(&mut self) {
        // 用 .change_to_cat() 把狗改成貓
        // 有了 &mut self 我們就能更改
        println!("Changing animal to cat!");
        self.animal_type = AnimalType::Cat;
    }

    fn check_type(&self) {
        // we want to read self
        match self.animal_type {
            AnimalType::Dog => println!("The animal is a dog"),
            AnimalType::Cat => println!("The animal is a cat"),
        }
    }
}



fn main() {
    let mut new_animal = Animal::new(); // 用關聯函式建立新動物
                                        // 它是一隻10歲的貓
    new_animal.check_type();
    new_animal.change_to_dog();
    new_animal.check_type();
    new_animal.change_to_cat();
    new_animal.check_type();
}

印出:

The animal is a cat
Changing animal to dog!
The animal is a dog
Changing animal to cat!
The animal is a cat

記住,Self(型別 Self)和 self(變數 self)是縮寫。(縮寫 = 簡寫方式)

所以在我們的程式碼中,Self = Animal。另外,fn change_to_dog(&mut self) 的意思是 fn change_to_dog(&mut Animal)

下面再舉一個小例子。這次我們將在 enum 上使用 impl

enum Mood {
    Good,
    Bad,
    Sleepy,
}

impl Mood {
    fn check(&self) {
        match self {
            Mood::Good => println!("Feeling good!"),
            Mood::Bad => println!("Eh, not feeling so good"),
            Mood::Sleepy => println!("Need sleep NOW"),
        }
    }
}

fn main() {
    let my_mood = Mood::Sleepy;
    my_mood.check();
}

印出 Need sleep NOW