当尝试从特征中的默认实现返回特征对象时,例如
trait Foo {
fn foo(self: Box<Self>) -> Box<dyn Foo> {
self
}
}
Run Code Online (Sandbox Code Playgroud)
Rust 编译器抱怨说
error[E0277]: the size for values of type `Self` cannot be known at compilation time
note: required for the cast to the object type `dyn Foo`
Run Code Online (Sandbox Code Playgroud)
类型转换应该是 from Box<Self>to Box<dyn Foo>,为什么这需要调整 Self 的大小?
将未调整大小的类型转换为特征对象是不可能的,因为这将迫使它同时具有两组元数据。
考虑这段代码:
trait Foo: 'static {
fn foo(self: Box<Self>) -> Box<dyn Foo> {
self
}
}
trait Bar {}
impl Foo for dyn Bar {}
impl Foo for i32 {}
impl<T> Bar for T {}
fn main() {
let boxed = Box::new(42);
boxed.foo();
let boxed: Box<dyn Bar> = Box::new(42);
boxed.foo();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,没有什么可以禁止最后一次调用 - 所有签名都允许它。但是,如果我们强制Box<dyn Bar>,那么 goBox<dyn Foo>的虚拟函数表会在哪里dyn Bar?(当然,在这种情况下它是空的,但它仍然必须存在 - 空特征并不特殊)
但是,如果添加where Self: Sized到foo,则最后一个调用将被正确拒绝:
error: the `foo` method cannot be invoked on a trait object
--> src/main.rs:20:11
|
2 | fn foo(self: Box<Self>) -> Box<dyn Foo> where Self: Sized {
| ----- this has a `Sized` requirement
...
20 | boxed.foo();
| ^^^
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |