我正在努力学习物体安全的基本知识.如果我有这个密码

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

When I add or remove : Sized as the supertrait or as f's bound, 我收到 slightly different error messages.

谁能解释一下:

  • 为什么这个例子不起作用?第Trait Objects章规定:

    那么,是什么让方法对象安全呢?每种方法都必须要求

    这不是满足了吗?

  • Trait: Sizedwhere Self: Sized之间有什么区别?(好吧,是的,一个继承了特征,另一个是参数绑定的,但是从Rust的特征对象的Angular 来看?

  • 我需要做的preferred个改变是什么?

如果重要的话,我用rustc 1.19.0-nightly (01951a61a 2017-05-20).

针对固定尺寸的 comments .

trait TraitB {
    fn f(&self) -> i32
    where
        Self: Sized;

    fn g<T>(&self, t: T) -> i32
    where
        Self: Sized;
}

推荐答案

为什么这个例子不起作用?第Trait Objects

那么,是什么让方法对象安全呢?每种方法都必须要求

这不是满足了吗?

这个问题真的是:What is a trait object

trait object是面向对象范例中的一个接口:

  • 它expose 了一系列有限的方法,
  • 适用于未知的混凝土类型.

操作所应用的具体类型是未知的,这就是为什么要使用trait对象,因为它允许以统一的方式操作一组异构类型.

然而,具体类型未知的事实意味着包含存储器的存储器区域的大小未知;因此,trait 对象只能在referencepointer后面操纵,例如&dyn TraitObject&mut dyn TraitObjectBox<dyn TraitObject>.

在内存级别上,它们中的每一个都以相同的方式表示:

  • 一个指向虚拟表的指针,它是一个 struct ,在固定的偏移量下,trait对象的每个"方法"都有一个函数指针,
  • 指向对象实际数据的指针.

Trait: Sized和where Self: Sized有什么区别?(嗯,是的,一个继承了特征,另一个是参数绑定的,但是从Rust的特征对象的Angular 来看?)

rust 没有遗传性.在both例中,这是bounds例:

  • Trait: Sized表示trait本身只能对已经实现Sized的类型实现,
  • fn method(&self) where Self: Sized表示只有实现Sized的类型才能实现此方法.

Note: when implementing a trait, all methods must end up having a definition; the latter is therefore only really useful if a default implementation is provided for the method with the 101 bound, as 100.

为了让object_safety_dynamic个成功,我最喜欢的改变是什么?

您必须通过引用或指针获取trait对象.是否使用引用或指针取决于是否要转移所有权.

Rust相关问答推荐

为什么单元类型(空元组)实现了`Extend`trait?

当为a Self:IntoIterator设置trait bind `时,获取`a T `不是迭代器"&'"<'>&'

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

如何为rust trait边界指定多种可能性

如何使用盒装枚举进行模式匹配?

当T不执行Copy时,如何返回Arc Mutex T后面的值?

如何使用Actix Web for Rust高效地为大文件服务

失真图像图形捕获Api

Rust:为什么 &str 不使用 Into

try 实现线程安全的缓存

UnsafeCell:它如何通知 rustc Select 退出基于别名的优化?

结果流到 Vec 的结果:如何避免多个into_iter和collect?

需要哪些编译器优化来优化此递归调用?

使用 Rust 从 Raspberry Pi Pico 上的 SPI 读取值

从光标位置旋转精灵

Rust 中的自动取消引用是如何工作的?

仅当函数写为闭包时才会出现生命周期错误

在 Rust 中,Weak 如何知道内部值何时被删除?

发生移动是因为 `data` 的类型为 `Vec`,它没有实现 `Copy` 特性

为什么当borrow 变量发生变化时,borrow 变量不会改变?