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{}
如果这么要求,那么这个函数或方法必须只能返回一种可能性结果(同一种类型)。
总结
- trait类似继承重写,可以把它理解为一个抽象公共模板接口。调用时就是用这个模板去实现内部的方法,但是这个方法在每个结构体里可以是不一样的。
trait 类{}
// impl 父类 for 类
// class 结构体(类)
impl 类 for 结构体
- 导入本地Trait的时候要在Cargo.toml修改[package]中的name字段。
eg: 假设name为demo,导入时:use demo::Summary;