我对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的一个超级特性,但它仍然给我带来了以下代码的问题:
一个二个一个一个
因为从Rust文档中了解到物体安全性
"大小"不一定是一种超特质,换句话说,它不一定需要"自我":尺寸。
我不知道现在该怎么办
1条答案
按热度按时间lb3vh1jj1#
Sized
结构体的字段可以存在于堆栈上,因此在编译时必须具有已知的大小。这就是Sized
错误所说明的。dyn Trait
是“任何实现Trait
的类型。那么它的大小是多少呢?嗯,这取决于底层类型是什么。因此,
dyn Trait
永远不会实现Sized
,即使Trait
具有Sized
作为超特性(所有这一切都保证了任何实现Trait
的类型也实现Sized
,但您仍然不知道它是 * 哪一个 *)。实际上,将
Sized
作为Trait
的超特性就是您如何选择退出对象安全性,这使得无法构造dyn Trait
。相反,解决这个问题的方法是使用类似指针的类型:
Box<dyn Trait>
创建自有指针&dyn Trait
创建引用Arc<dyn Trait>
创建引用计数指针指针类型的选择取决于您的用例,但在大多数情况下,
Box<dyn Trait>
是合适的,并且是一个很好的起点。