rust 我如何拥有一个trait作为一个结构体的拥有域?

pu3pd22g  于 2023-02-19  发布在  其他
关注(0)|答案(1)|浏览(168)

我对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文档中了解到物体安全性
"大小"不一定是一种超特质,换句话说,它不一定需要"自我":尺寸。
我不知道现在该怎么办

lb3vh1jj

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>是合适的,并且是一个很好的起点。

相关问题