Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

トレイト

trait は、未知の型 Self に対して定義されたメソッドの集合です。 同じトレイト内で宣言された他のメソッドにアクセスできます。

トレイトは任意のデータ型に対して実装できます。以下の例では、 メソッドのグループである Animal を定義します。その後、Animal traitSheep データ型に対して実装し、SheepAnimal のメソッドを 使用できるようにします。

struct Sheep { naked: bool, name: &'static str }

trait Animal {
    // 関連関数のシグネチャ。`Self` は実装側の型を指します。
    fn new(name: &'static str) -> Self;

    // メソッドのシグネチャ。これらは文字列を返します。
    fn name(&self) -> &'static str;
    fn noise(&self) -> &'static str;

    // トレイトはデフォルトのメソッド定義を提供できます。
    fn talk(&self) {
        println!("{} が {} と言う", self.name(), self.noise());
    }
}

impl Sheep {
    fn is_naked(&self) -> bool {
        self.naked
    }

    fn shear(&mut self) {
        if self.is_naked() {
            // 実装側のメソッドは、実装側のトレイトメソッドを使用できます。
            println!("{} はすでに裸です...", self.name());
        } else {
            println!("{} が毛を刈られました!", self.name);

            self.naked = true;
        }
    }
}

// `Sheep` に対して `Animal` トレイトを実装します。
impl Animal for Sheep {
    // `Self` は実装側の型、つまり `Sheep` です。
    fn new(name: &'static str) -> Sheep {
        Sheep { name: name, naked: false }
    }

    fn name(&self) -> &'static str {
        self.name
    }

    fn noise(&self) -> &'static str {
        if self.is_naked() {
            "メェェェ?"
        } else {
            "メェェェ!"
        }
    }

    // デフォルトのトレイトメソッドはオーバーライドできます。
    fn talk(&self) {
        // たとえば、少し静かな黙考を加えることができます。
        println!("{} は少し間を置いた... {}", self.name, self.noise());
    }
}

fn main() {
    // この場合、型アノテーションが必要です。
    let mut dolly: Sheep = Animal::new("Dolly");
    // TODO ^ 型アノテーションを削除してみてください。

    dolly.talk();
    dolly.shear();
    dolly.talk();
}