trait特征

3 阅读2分钟

trait 是 Rust 中的接口,它定义了类型使用这个接口的行为。

A. trait ... (定义契约)

这是在“设计蓝图”或“设计徽章”。

  • 关键字:  trait

  • 目的:  定义一个共享的行为契约。

  • 例子:

    Rust

    // 我设计一个“会说话”的徽章
    trait CanSpeak {
        // 必须实现:你必须有 speak 方法
        fn speak(&self) -> String; //所有未给出默认值的都是必须用的
    
        // 可选实现:我提供一个默认的 shout 方法
        fn shout(&self) -> String {
            self.speak().to_uppercase() + "!!"
        }
    }
    

B. impl Trait for Struct (实现契约)

这是在“佩戴徽章”,并告诉大家你是如何做到的。

  • 关键字:  impl ... for ...

  • 目的:  为一个 struct (或 enum) 实现一个 trait (契约)。

  • 例子:

    Rust

    struct Person {
        name: String,
    }
    
    // 我为 Person “实现 (impl)” “CanSpeak (for)”
    impl CanSpeak for Person {
        // 我必须实现 trait 里的 speak 方法
        fn speak(&self) -> String {
            format!("My name is {}", self.name)
        }
    
        // 我也可以选择不实现 shout,用默认的。
        // 但我也可以选择“覆盖”它:
        fn shout(&self) -> String {
            "I'M SHOUTING!".to_string()
        }
    }
    

C. impl Struct (实现 struct 自己的方法)

这是在“给 struct 添加它自己的、与契约无关的”方法。

  • 关键字:  impl (后面只有一个名字)

  • 目的:  为 struct 定义“固有方法”(Inherent Methods),比如构造函数 ::new()

  • 例子:

    Rust

    // 我为 Person 实现它自己的方法
    impl Person {  为 Complex 这个结构体定义方法
        // 这是一个“构造函数”
        // 它不属于 CanSpeak,它只是 Person 自己的
        pub fn new(name: &str) -> Self { // 2. 定义一个公开的静态函数,返回类型是自身
            Self {
                name: name.to_string(), 3. 创建并返回实例
            }
        }
    }
    
    `pub`: 表示这个函数是**公开的**(public)。别的模块(文件)也可以调用它。如果不写 `pub`,它只能在当前模块内部使用。
    

他的完整写法是

Person {
 name :name
}

`impl` 关键字就是“**实现**”:

    impl MyStruct:实现 `MyStruct` 自己的方法。
    impl MyTrait for MyStruct:为 `MyStruct` 实现 `MyTrait` 这个契约。
    

关联函数

允许内部包含方法,也就是关联函数

pub trait Parse {
   fn parse(s:&str) -> Result<Self, E>
}

关联类型

pub trait parse {
   type Error;
   
   fn parse(s:&str) -> Result<Self,Self::Error>
}

继承

在 Rust 中,一个 trait 可以“继承”另一个 trait 的关联类型和关联函数。比如 trait B: A,是说任何类型 T,如果实现了 trait B,它也必须实现 trait A,换句话说,trait B 在定义时可以使用 trait A 中的关联类型和方法。

而特设多态是同一种行为的不同实现。所以其实,通过定义 trait 以及为不同的类型实现这 个 trait,我们就已经实现了特设多态

具体类型可以查看14,每个trait的具体实现