スーパートレイト(@Rust)

Rustに継承はないですが、似たような機能ということであるトレイトの上位トレイトを定義可能です。

Trait_b: Trait_aのような記法でTrait_aがスーパートレイトでTarit_bはサブトレイトになります。

https://doc.rust-jp.rs/rust-by-example-ja/trait/supertraits.html

にサンプルコードがありますが、main()から呼べるようにしたのが以下のコードでGeminiで追加部分のコードをジェネレートしましたが、構造体CSStudentを定義して必要な関数を実装し、main()からは構造体のインスタンスを作成して関数comp_sci_student_greeting()を呼び出しています。

// Define a struct that implements CompSciStudent
struct CSStudent { 
    name: String,
    university: String,
    fav_lang: String,
    git_username: String,
}

trait Person {
    fn name(&self) -> String;
}

// Person is a supertrait of Student.
// Implementing Student requires you to also impl Person.
trait Student: Person {
    fn university(&self) -> String;
}

trait Programmer {
    fn fav_language(&self) -> String;
}

// CompSciStudent (computer science student) is a subtrait of both Programmer
// and Student. Implementing CompSciStudent requires you to impl both supertraits.
trait CompSciStudent: Programmer + Student {
    fn git_username(&self) -> String;
}

fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
    format!(
        "My name is {} and I attend {}. My favorite language is {}. My Git username is {}",
        student.name(),
        student.university(),
        student.fav_language(),
        student.git_username()
    )
}

impl Person for CSStudent {
    fn name(&self) -> String {
        self.name.clone()
    }
}

impl Student for CSStudent {
    fn university(&self) -> String {
        self.university.clone()
    }
}

impl Programmer for CSStudent {
    fn fav_language(&self) -> String {
        self.fav_lang.clone()
    }
}

impl CompSciStudent for CSStudent {
    fn git_username(&self) -> String {
        self.git_username.clone()
    }
}

fn main() {
    let bob = CSStudent {
        name: "Bob".to_string(),
        university: "Cambridge".to_string(),
        fav_lang: "Ruby".to_string(),
        git_username: "claw".to_string(),
    };

    println!("{}", comp_sci_student_greeting(&bob));
}

ここで&dyn CompSciStudentの記法がありますが、トレイトオブジェクトと呼ばれる動的ディスパッチです。

dyn prefix(@Rust)

これはコンパイル時にサイズが決定できないので&dynを使い、またdynはfat pointerです。さらに&dyn CompScistudentはimpl CompScistudentでもコンパイル可能で、impl Traitで静的に呼び出しもできます。静的指定に比べると多少なりとも負荷は増加しますが、

https://isehara-3lv.sakura.ne.jp/blog/2024/06/04/impl-traitはstaticであるrust/

 

admin

カテゴリーRust