Rust 特征trait
trait类似于java中的接口
基本定义
trait Printable {
fn format(&self) -> String;
}
为类型实现trait
struct Book {
title: String,
pages: u32,
}
impl Printable for Book {
fn format(&self) -> String {
format!("《{}》({})页", self.title, self.pages);
}
}
泛型trait
trait Converter<T> {
fn convert(&self) -> T;
}
impl Converter<f64> for Book {
fn convert(&self) -> f64 {
self.pages as f64
}
}
泛型约束
fn print_info<T: Printable> (item: T) {
println!("{}", item.format());
}
// 等价于
fn print_info(item: impl Printable) {
println!("{}", item.format());
}
// 返回值实现trait
fn create_printable() -> impl Printable { }
条件实现
// 根据类型特征选择性实现
impl<T: Display> Printable for T {
}
trait继承
trait Animal: Printable + Clone {
fn speak(&self);
}
动态分发
多态, 用&dyn Trait表示一个trait对象的引用,可变引用&mut dyn Trait
由两个指针组成,一个指向实际类型,一个执行改类型实现trait方法的函数指针表
对象安全
只有满足以下条件的trait才能作为dyn Trait使用
- 方法不能返回Self
- 方法不能使用泛型参数
- 方法不能携带 Sized 约束(where Self: Sized)
trait Animal {
fn speak(&self);
}
struct Cat;
struct Dog;
impl Animal for Cat {
fn speak(&self) {
println!("喵");
}
}
impl Animal for Dog {
fn speak(&self) {
println!("汪");
}
}
fn main() {
let cat = Cat;
let dog = Dog;
let animals: Vec<&dyn Animal> = vec![&cat, &dog];
for animal in animals {
animal.speak();
}
}

浙公网安备 33010602011771号