Rust Trait

Trait

Trait告诉rust编译器某种类型具有哪些并且可以与其他类型共享的功能。抽象的定义共享行为。

有点类似继承。

定义一个Trait

trait Summary {
    // 只创建方法,声明签名
    fn summarize(&self) -> String;
}

在类型实现trait

impl Xxxx for Tweet {...}
Tweet是类型名,这里是个结构体。

当一个类型定义了trait之后,可以直接使用这个trait方法。

比如Tweet struct实现了Summary这个trait,并且trait里有个summarize方法。main函数中又实例化了一个article的Tweet struct,那么可以直接使用article.summarize()

来自trait里的东西在作用域里才能使用。

在trait里也可以做默认实现

默认实现的方法可以调用trait中其他的方法,即使这些方法没有默认实现。但是在具体事例上使用这个默认方法,就必须先把其他方法实现了。

Trait bounds

要求泛型类型的参数实现了某些Trait。

前提条件:这个类型或trait是在本地crate里定义的。(不准重写源码,孤儿规则)

Trait 作为参数

pub fn notify(itemi: impl Summary, itemk: impl Summary){}
要求传入的item必须实现了Summary的trait,这样就可以实现itemi.Summary里的方法

pub fn notify<T: Summary>(item: T){}
使用trait bound写法。

要求同时实现两个trait

use std::fmt::Display;
pub fn notify(itemi: impl Summary + Display){}

pub fn notify<T: Summary + Display>(item: T){}

where指定trait约束

冗余的写法
pub fn notify<T: Summary + Display, U: Clone + Debug>(a: T, b: U) -> String {a.summarize()}

where写法

pub fn notify<T, U>(a: T, b: U) -> String
where
  T: Summary + Display,
  U: Clone + Debug,
{a.summarize()}

返回类型要求实现某个trait

pub fn notify(s: &str) -> impl Summary{}

如果这么要求,那么这个函数或方法必须只能返回一种可能性结果(同一种类型)。

总结

  1. trait类似继承重写,可以把它理解为一个抽象公共模板接口。调用时就是用这个模板去实现内部的方法,但是这个方法在每个结构体里可以是不一样的。
trait 类{}

// impl 父类 for 类
// class 结构体(类)
impl 类 for 结构体
  1. 导入本地Trait的时候要在Cargo.toml修改[package]中的name字段。
    eg: 假设name为demo,导入时:
    use demo::Summary;
posted @ 2021-12-01 14:23  阿初  阅读(194)  评论(0编辑  收藏  举报