前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rust数组默认初始化:初始化未实现Copy trait的类型

Rust数组默认初始化:初始化未实现Copy trait的类型

作者头像
灯珑LoGin
发布2023-10-18 10:43:53
3370
发布2023-10-18 10:43:53
举报
文章被收录于专栏:龙进的专栏

在安全的Rust中,编译器要求数组一旦被声明,它所占用的内存应当被完全初始化。但是,在一些情况下,这样会导致没法很灵活的对数组进行默认初始化。

问题

请看这个例子:

对于这样一个结构体,我们要初始化[Option<File>; FileDescriptorVec::PROCESS_MAX_FD]这个数组,想要把它的每个元素默认初始化为None。并且,由于其它的原因,我们不能够为File结构体实现Copy Trait.

如果我们使用这样的方式来把数组初始化为None:

就会报错:

报错的原因是,File结构体未实现Copy Trait,导致我们用None对Option<T>进行默认初始化的时候,编译器无法直接把Option<T>复制到数组的每个元素之中。

上文说到,由于其他原因的限制,我们不能为File实现Copy这个trait,因此,我们需要找别的方法,初始化这个数组。

解决方案:MaybeUninit

不安全的 Rust 给了我们一个强大的工具来处理这个问题:MaybeUninit。这个类型可以用来处理还没有完全初始化的内存。通过使用MaybeUninit,我们可以对一个数组进行逐个元素的初始化。

首先,我们声明一个MaybeUninit的类型的数组:

这个数组的元素类型就是MaybeUninit<Option<File>>,并且,在代码里面,我们通过assume_init()声称已经完全初始化了它。这听着不靠谱,但是,MaybeUninit本身就不需要初始化,因此,我们假设它已经初始化,是没有问题的。但是,请注意,这样会产生一个无效的类型实例(因为Option<File>实际上没有被初始化),并且会带来一些未定义的行为。

接着,我们在一个循环里面,初始化这个数组:

有的同学可能会疑惑:这样赋值不就导致了原先的”MaybeUninit”类型上面产生了一个drop了吗?

答案就是,MaybeUninit的类型,它的Drop Trait,产生的动作就是:“什么也不做”。也就是说,不会调用内层的类型的Drop方法。

在上面这段代码过后,整个数组都被初始化为None了,一切准备就绪,我们使用以下代码,把“未初始化”的类型,强制转换为“已经初始化”的类型:

于是,我们就能用这个data,去初始化FileDescriptorVec结构体了!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023年3月8日20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 解决方案:MaybeUninit
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档