Rust 中的特征对象是如何实现的?
How are trait objects implemented in Rust?
我想了解 trait 对象是如何在 Rust 中实现的。下面的理解是否正确,请指教。
我有一个函数接受任何实现 Write
特征的类型:
fn some_func(write_to: &mut Write) {}
在我们有实现此特征并调用上述函数的类型的任何地方,编译器都会生成一个 "trait object",可能是通过添加对 TraitObject::new(data, vtable)
.
的调用
如果我们有类似的东西:
let input = get_user_input(); // say we are expecting the input to be 1 or 2
let mut file = File::new("blah.txt").unwrap();
let mut vec: Vec<u8> = vec![1, 2, 3];
match input {
1 => some_func(&mut file),
2 => some_func(&mut vec),
}
可能会变成:
match input {
1 => {
let file_write_trait_object: &mut Write =
TraitObject::new(&file, &vtable_for_file_write_trait);
some_func(file_write_trait_object);
}
2 => {
let vec_write_trait_object: &mut Write =
TraitObject::new(&vec, &vtable_for_vec_write_trait);
some_func(vec_write_trait_object);
}
}
在 some_func
内部,编译器将仅访问基于传递的 TraitObject
中的 vtable 使用的方法。
Trait 对象是胖指针,所以 fn some_func(write_to: &mut Write)
编译成 fn some_func(_: *mut OpaqueStruct, _: *const WriteVtable)
.
我想了解 trait 对象是如何在 Rust 中实现的。下面的理解是否正确,请指教。
我有一个函数接受任何实现 Write
特征的类型:
fn some_func(write_to: &mut Write) {}
在我们有实现此特征并调用上述函数的类型的任何地方,编译器都会生成一个 "trait object",可能是通过添加对 TraitObject::new(data, vtable)
.
如果我们有类似的东西:
let input = get_user_input(); // say we are expecting the input to be 1 or 2
let mut file = File::new("blah.txt").unwrap();
let mut vec: Vec<u8> = vec![1, 2, 3];
match input {
1 => some_func(&mut file),
2 => some_func(&mut vec),
}
可能会变成:
match input {
1 => {
let file_write_trait_object: &mut Write =
TraitObject::new(&file, &vtable_for_file_write_trait);
some_func(file_write_trait_object);
}
2 => {
let vec_write_trait_object: &mut Write =
TraitObject::new(&vec, &vtable_for_vec_write_trait);
some_func(vec_write_trait_object);
}
}
在 some_func
内部,编译器将仅访问基于传递的 TraitObject
中的 vtable 使用的方法。
Trait 对象是胖指针,所以 fn some_func(write_to: &mut Write)
编译成 fn some_func(_: *mut OpaqueStruct, _: *const WriteVtable)
.