我最近看到了使用 dyn
关键字的代码:
fn foo(arg: &dyn Display) {}
fn bar() -> Box<dyn Display> {}
这个语法是什么意思?
// As a trait
impl MyTrait for SomeType {}
// As a type!
impl MyTrait {}
impl AnotherTrait for MyTrait {}
MyTrait
类型是一个不定大小/动态大小的类型,这可能会给人们带来非常复杂的错误信息。dyn
语法。这个语法从Rust 1.27开始可用。use std::{fmt::Display, sync::Arc};
fn main() {
let display_ref: &dyn Display = &42;
let display_box: Box<dyn Display> = Box::new(42);
let display_arc: Arc<dyn Display> = Arc::new(42);
}
简介:"dyn" 允许您将苹果和橙子混合存储在一个 Box 中,因为它们都实现了 Fruit 这个 trait,而这正是您的 Box 用作类型约束的内容,而不仅仅是一个通用类型。这是因为泛型只允许其中的一个是 Apple 或 Orange,而不是两者都是:
Vec<Box<T>> --> Vector can hold boxes of either Apples OR Oranges structs
Vec<Box<dyn Fruit>> --> Vector can now hold a mix of boxes of Apples AND Oranges Structs
struct Service<T:Backend>{
backend: Vec<T> // Either Vec<TypeA> or Vec<TypeB>, not both
}
...
let mut backends = Vec::new();
backends.push(TypeA);
backends.push(TypeB); // <---- Type error here
vs
struct Service{
backends: Vec<Box<dyn Backend>>
}
...
let mut backends = Vec::new();
backends.push( Box::new(PositiveBackend{}) as Box<dyn Backend>);
backends.push( Box::new(NegativeBackend{}) as Box<dyn Backend>);
dyn
关键字用于指示类型为特征对象。根据Rust文档:
换句话说,我们在编译时不知道对象的具体类型,只知道该对象实现了该特征。特征对象是另一种类型的不透明值,它实现了一组特征。
Trait
是您的特征名称,则可以按以下方式使用特征对象:
Box<dyn Trait>
&dyn Trait
请查看我的什么是“trait对象”的回答以获取更多细节。