rust - 如何将特征作为结构的自有字段?

标签 rust struct traits borrow-checker

我对 Rust 相当陌生,我试图实现一个结构,该结构可以具有不同的结构,这些结构将共同特征实现为字段

在带有垃圾收集器的传统编程语言中,我会像这样实现它:


pub struct MemoryMapper {
    regions: Vec<Region>,
}

trait MemoryMappable: Sized {
    
}

pub struct Region {
    device: dyn MemoryMappable,
    start: u32,
    end: u32,
    remap: bool
}

但是这里我有以下编译错误:

the size for values of type `(dyn MemoryMappable + 'static)` cannot be known at compilation time
the trait `Sized` is not implemented for `(dyn MemoryMappable + 'static)`
only the last field of a struct may have a dynamically sized type
change the field's type to have a statically known size

我已经尝试使 Sized 成为 MemoryMappable 的 super 特征,但它仍然给我带来了以下代码的问题:

pub fn map(&mut self, device: dyn MemoryMappable, start: u32, end: u32, remap: bool) -> &Region {
        self.regions.insert(0, Region{device, start, end, remap});
        return self.regions.get(0).unwrap();
}
the trait `MemoryMappable` cannot be made into an object
`MemoryMappable` cannot be made into an object

因为来自Rust documentation about object safety

Sized must not be a supertrait. In other words, it must not require Self: Sized.

我现在不知道该怎么做

最佳答案

Sized 的字段结构可以存在于堆栈中,因此在编译时必须具有已知的大小。这就是Sized错误是说。

dyn Trait是“任何实现 Trait 的类型。那么它的大小是多少?嗯,这取决于底层类型是什么。

因此,dyn Trait从未实现Sized ,即使TraitSized作为一个 super 特征(所有这一切都是保证任何实现 Trait 的类型也实现 Sized ,但你仍然不知道它是哪一个)。

事实上,制作 Sized Trait 的 super 特征这就是您选择退出对象安全的方式,这使得无法构建 dyn Trait .

相反,解决这个问题的方法是使用类似指针的类型:

  • Box<dyn Trait>创建一个拥有的指针
  • &dyn Trait创建引用
  • Arc<dyn Trait>创建一个引用计数指针
  • 等等

指针类型的选择取决于您的用例,但在大多数情况下,Box<dyn Trait>很好,并且是一个很好的起点。

关于rust - 如何将特征作为结构的自有字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75492513/

相关文章:

Rust:打印作为参数传入的函数的名称

rust - 如何返回 impl Trait,其中类型的引用实现了该特征?

c - 关于列表和指针 C 的考试练习

c++ - 头文件中的结构无法识别

scala - 对于 "trait Queue[T]", `Queue` 是一种类型吗?

rust - 无法运行一个简单的例子 -- "use of unstable library feature ' rustc_private' : . ...."

struct - Lisp 中的嵌套结构

php - Codeigniter 3 : How to use composer packages?(Twilio SDK)

generics - 泛型结构的构造函数中出现 "Expected type parameter"错误

rust - 如何在结构中存储递归引用