面试题答案
一键面试1. Trait对象动态派发原理
在Rust中,trait对象通过胖指针(fat pointer)来实现动态派发。胖指针实际上包含两个部分:一个指向数据的指针,另一个指向虚表(vtable)的指针。虚表是一个函数指针的列表,其中每个函数指针对应trait中定义的方法。当通过trait对象调用方法时,Rust运行时系统会根据虚表找到对应的函数指针,并调用相应的函数,从而实现动态派发。
2. 定义trait和trait对象示例
// 定义一个trait
trait Animal {
fn speak(&self);
}
// 定义实现Animal trait的结构体
struct Dog;
impl Animal for Dog {
fn speak(&self) {
println!("Woof!");
}
}
struct Cat;
impl Animal for Cat {
fn speak(&self) {
println!("Meow!");
}
}
fn main() {
// 创建trait对象
let animals: Vec<Box<dyn Animal>> = vec![Box::new(Dog), Box::new(Cat)];
// 通过trait对象调用trait方法
for animal in animals {
animal.speak();
}
}
在上述代码中:
- 首先定义了
Animal
trait,包含一个speak
方法。 - 然后定义了
Dog
和Cat
结构体,并为它们实现了Animal
trait。 - 在
main
函数中,创建了一个包含Box<dyn Animal>
的Vec
,这就是trait对象的集合。Box<dyn Animal>
表示指向实现了Animal
trait 的动态大小类型的指针。 - 最后通过遍历
animals
向量,调用每个trait对象的speak
方法,实现了动态派发。