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的具体实现