我对 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
,即使Trait
有Sized
作为一个 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/