我正在为对象安全的基础知识苦苦挣扎。如果我有这段代码
struct S {
x: i32,
}
trait Trait: Sized {
fn f(&self) -> i32
where
Self: Sized;
}
fn object_safety_dynamic(x: Trait) {}
我收到了
error[E0038]: the trait `Trait` cannot be made into an object
--> src/lib.rs:11:29
|
5 | trait Trait: Sized {
| ----- ----- ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
...
11 | fn object_safety_dynamic(x: Trait) {}
| ^^^^^ the trait `Trait` cannot be made into an object
当我添加或删除 : Sized
作为超特征或 f
的绑定(bind)时,我收到略有不同的错误消息。
谁能解释一下:
为什么这个特定示例不起作用?本章Trait Objects状态:
So what makes a method object-safe? Each method must require that
Self: Sized
这不是实现了吗?
Trait: Sized
和where Self: Sized
有什么区别? (嗯,是的,一个继承了 trait,另一个是参数绑定(bind),但是从 Rust 的 trait 对象的角度来看?要使
object_safety_dynamic
正常工作,我必须进行哪些首选更改?
如果重要的话,我正在使用 rustc 1.19.0-nightly (01951a61a 2017-05-20)
。
解决关于固定尺寸的评论。
trait TraitB {
fn f(&self) -> i32
where
Self: Sized;
fn g<T>(&self, t: T) -> i32
where
Self: Sized;
}
最佳答案
Why does this particular example not work? The chapter Trait Objects states:
So what makes a method object-safe? Each method must require that
Self: Sized
这不是实现了吗?
这个问题实际上是:什么是特征对象?
trait 对象 是面向对象范例中的接口(interface):
- 它公开了一组有限的方法,
- 应用于未知的具体类型。
应用操作的具体类型是未知的这一事实正是人们使用特征对象的原因,因为它允许以统一的方式操作一组异构类型一直到汇编级别.
然而,具体类型未知的事实意味着包含内存的内存区域的大小也未知;因此,特征对象只能在引用 或指针 之后操作,例如&dyn TraitObject
, &mut dyn TraitObject
或 Box<dyn TraitObject>
例如。
在内存级别,它们中的每一个都以相同的方式表示:
- 指向虚拟表的指针,它是一种结构,在固定偏移处为特征对象的每个“方法”保存一个函数指针,
- 指向对象实际数据的指针。
What is the difference between
Trait: Sized
and whereSelf: Sized
? (Well, yes, one inherits the trait the other one is a parameter bound, but from Rust's trait object perspective?)
Rust 中没有继承。在两种情况下,它们都是边界:
-
Trait: Sized
指出特征本身只能为已经实现Sized
的类型实现, -
fn method(&self) where Self: Sized
指出只有实现Sized
的类型可以实现这个方法。
注意:当实现一个 trait 时,所有的方法最终都必须有一个定义;因此后者只有在为带有 Self: Sized
的方法提供默认实现时才真正有用。绑定(bind),如is shown here .
What is the preferred change I had to make
object_safety_dynamic
work?
您必须通过引用或指针获取特征对象。使用引用还是指针取决于您是否要转让所有权。
关于rust - 了解特征和对象安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44096235/