我对Rust还很陌生,我打算实现一个 struct ,该 struct 可以具有不同的 struct ,该 struct 将一个共同的特征实现为一个字段

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


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

我曾try 将Size设置为MemoyMappable的一个附加特征,但它仍然让我在以下代码中遇到问题:

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个 struct 的字段,因此在编译时必须具有已知大小.这就是Sized错误所说的.

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

因此,dyn Trait永远不会实现Sized,即使TraitSized作为超特征(这样做只是保证实现Trait的任何类型也实现Sized,但您仍然不知道它是which one).

事实上,将Sized作为Trait的超级特性是您 Select 退出对象安全的方式,这使得构建dyn Trait是不可能的.

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

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

指针类型的 Select 取决于您的用例,但在大多数情况下,Box<dyn Trait>就可以了,这是一个很好的起点.

Rust相关问答推荐

移植带有可变borrow 的C代码-卸载期间错误(nappgui示例)

为什么父作用域中的变量超出了子作用域

将此字符串转换为由空格字符分隔的空格

在Rust中有没有办法在没有UB的情况下在指针和U64之间进行转换?

在rust sqlx中使用ilike和push bind

我可以在不收集或克隆的情况下,将一个带有Item=(key,val)的迭代器拆分成单独的key iter和val iter吗?

我如何使用AWS SDK for Rust获取我承担的角色的凭据?

正在将带有盒的异步特征迁移到新的异步_fn_in_特征功能

如何设置activx websocket actorless的消息大小限制?

Rust 中什么时候可以返回函数生成的字符串切片&str?

这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

需要一个有序向量来进行 struct 初始化

我可以用 Rust 编写一个不可变变量

max(ctz(x), ctz(y)) 有更快的算法吗?

在 Rust 中,我如何处理请求 javascript 的页面?

Rust 引用元组和引用元组

If let expression within .iter().any

意外的正则表达式模式匹配

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成

函数参数的 Rust 功能标志