wro*_*ame 7 rust trait-objects
我理解的规则,当一个特征可以做成一个特征对象,但我不明白为什么这些规则的存在。
例如:
trait Resource {
const RESOURCE_ID: u64;
}
trait ResourceStatic {
fn static_id() -> u64;
}
trait ResourceInstance {
fn resource_id(&self) -> u64;
}
struct MyResource {}
impl Resource for MyResource {
const RESOURCE_ID: u64 = 123;
}
impl ResourceStatic for MyResource {
fn static_id() -> u64 {
123
}
}
impl ResourceInstance for MyResource {
fn resource_id(&self) -> u64 {
123
}
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这三个特征基本上都封装了相同的功能。那么为什么这些是不允许的:
let _: Box<dyn Resource> = Box::new(MyResource{});
let _: Box<dyn ResourceStatic> = Box::new(MyResource{});
Run Code Online (Sandbox Code Playgroud)
但这是?
let _: Box<dyn ResourceInstance> = Box::new(MyResource{});
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下幕后发生的事情,使其看起来不随意吗?
什么是特质对象?这是
这个定义足以解释为什么ResourceInstancewhile 有效Resource和ResourceStatic不起作用。
ResourceInstancetrait ResourceInstance {
fn resource_id(&self) -> u64;
}
Run Code Online (Sandbox Code Playgroud)
该特征可以制成一个对象,因为即使具体类型未知,您仍然可以调用resource_id实现该特征的值(通过将其作为self参数传递)。
ResourceStatictrait ResourceStatic {
fn static_id() -> u64;
}
Run Code Online (Sandbox Code Playgroud)
这个特征不能成为一个对象,因为static_id可以在没有值的情况下调用,这意味着为了调用static_id你必须知道具体类型。
对于每个特征对象类型(例如dyn ResourceStatic),编译器自动生成相应特征()的实现ResourceStatic。此自动实现使用 vtable 指针作为self特征方法中类型的一部分传递。当没有self类型时,就没有 vtable 指针,编译器无法自动实现该方法。Rust 中没有“裸 vtable 指针”。
为了更好地理解这一点,想象dyn ResourceStatic是一种有效的类型。有什么<dyn ResourceStatic>::static_id()作用?它不能遵循具体类型的实现,因为没有值,因此没有具体类型。我们是否应该得出这样的结论:dyn ResourceStatic 不实施 ResourceStatic?这显然是错误的。或者是否dyn ResourceStatic有自己的实现ResourceStatic,不遵循某些具体类型?这也没有意义,因为 的全部意义dyn ResourceStatic就是代表具体类型。
Rust 解决这个问题的方法就是简单地拒绝dyn ResourceStatic作为一种类型。
Resourcetrait Resource {
const RESOURCE_ID: u64;
}
Run Code Online (Sandbox Code Playgroud)
这个特征不能成为一个对象,原因与ResourceStatic不能一样:因为特征对象类型不可能dyn Resource自动满足特征的要求。
如果您想在类型上进行动态调度Self,则需要一个self参数来进行调度。
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |