dyn
是特征(trait,类似java中的interface)对象类型的前缀,dynamic的缩写。比如你有一个trait名字叫做Writable,你可以用dyn Writable表示实现了Writable特征的struct。
dyn关键字用于强调调用相关特征的方法是动态分配的,即运行时才知道调用的是哪个实现了特征的结构体(类似java的运行时多态)。
不像范型参数或者impl Trait
,编译器无法知道调用的时候被传递的具体类型是什么。也就是说,类型信息被擦除了。就其本身而言,一个dyn Trait
引用包含两个指针。一个指针指向数据(比如一个结构体的实例)。另一个指针指向方法名与函数指针的map(也叫做虚方法表)。
在运行时,当需要调用dyn Trait
上的方法的时候,会查询虚方法表以获取函数指针,然后去调用查找到的函数指针。
使用dyn Trait
的一个例子:
fn main() {
let mut personList: Vec<Box<dyn Role>> = Vec::new();
let student = Student;
let teacher = Teacher;
personList.push(Box::new(student));
personList.push(Box::new(teacher));
// 下面这行会报错:the trait `Role` is not implemented for `&str` required for the cast to the object type `dyn Role`
// personList.push(Box::new("test"));
for p in personList {
p.print_role();
}
}
struct Student;
struct Teacher;
trait Role {
fn print_role(&self);
}
impl Role for Student {
fn print_role(&self) {
println!("role is student");
}
}
impl Role for Teacher {
fn print_role(&self) {
println!("role is teacher");
}
}
参考资料:
1.https://doc.rust-lang.org/std/keyword.dyn.html