Skip to content

Trait

什么是trait

一个类型的行为由其可供调用的方法构成。如果可以对不同类型调用相同的方法的话,这些类型就可以共享相同的行为了。trait 定义是一种将方法签名组合起来的方法,目的是定义一个实现某些目的所必需的行为的集合。trait的定义:

rust
pub trait Introduction {
    fn introduction(&self);
}

这里使用 trait 关键字来声明一个 trait,后面是 trait 的名字,在这个例子中是 Introduction

我们也声明 traitpub(即public简写) 以便依赖这个 crate 的 crate 也可以使用这个trait。在大括号中声明描述实现这个 trait 的类型所需要的行为的方法签名,在这个例子中是 fn introduction(&self)

在方法签名后跟分号,而不是在大括号中提供其实现。接着每一个实现这个 trait 的类型都需要提供其自定义行为的方法体,编译器也会确保任何实现 Introduction trait 的类型都拥有与这个签名的定义完全一致的 introduction 方法。

trait 体中可以有多个方法:一行一个方法签名且都以分号结尾。

trait的示例:

rust
trait Introduction {         // 定义了trait名:Introduction
    fn introduction(&self);  // 该trait的行为introduction,也就是函数的声明
}
// 以下两个结构体有一个共同的行为就是打印输出
struct Cat;
impl Introduction for Cat {   // 为类型实现 trait 的语法格式
    fn introduction(&self) {
        println!("hello, i am a Cat");
    }
}
struct Dog;
impl Introduction for Dog {
    fn introduction(&self) {
        println!("hello, i am a Dog");
    }
}
fn main() {
    let c = Cat{};
    c.introduction();
    
    let d = Dog{};
    d.introduction();
}

trait 类似于其他语言中的常被称为 接口interfaces)的功能。trait 定义了一个可以被共享的行为,只要实现了 trait,你就能使用该行为

默认实现trait

有时为 trait 中的某些或全部方法提供默认的行为,而不是在每个类型的每个实现中都定义自己的行为是很有用的。这样当为某个特定类型实现 trait 时,可以选择保留或重载每个方法的默认行为。例如可以在trait的定义中使用默认实现:

rust
pub trait Introduction {
    fn introduction(&self) {
        println!("Hello");
    }
}

如果想要使用这个默认实现,而不是定义一个自己的实现,则可以通过 impl Introduction for Dog {} 指定一个空的 impl 块。例如:

rust
trait Introduction {   
    // 默认实现
    fn introduction(&self) {
        println!("Hello");  
    }
}

struct Cat;
// 使用默认实现
impl Introduction for Cat {}

// 不使用默认实现,自定义实现
struct Dog;
impl Introduction for Dog {
    fn introduction(&self) {
        println!("hello, i am a Dog");
    }
}
fn main() {
    let c = Cat{};
    c.introduction();
    
    let d = Dog{};
    d.introduction();
}