rust - 让编译器相信数组的每个索引都将被初始化

标签 rust

我正在尝试为 20 个元素的缓冲区实现 Rand 特征,这些元素本身实现 Rand 特征。我遍历缓冲区并使用随机值初始化每个元素。但是,我无法让编译器相信 buff 最终会完全初始化。

我应该怎么做才能让它接受这一点?

extern crate rand;
use rand::{Rand, Rng};

struct Buf20<T>([T; 20]);

impl<T: Rand> Rand for Buf20<T> {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        let mut buff : [T; 20];
        for element in &mut buff {
            *element = rng.gen();
        }
        Buf20(buff)
    }
}

最佳答案

你无法让编译器相信这一点,因为它不一定是真的。

这里有两个未知类型,TR ,他们的相互作用可能会破坏这里的事情。以下是 Rand 的几种可能的实现方式和Rng这会让它爆炸:

struct T(Box<u32>);

impl Rand for T {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        T(Box::new(rng.next_u32()))
    }
}

struct R(u32);

impl Rng for R {
    fn next_u32(&mut self) -> u32 {
        let next = self.0;
        self.0 += 1;
        if self.0 > 10 {
            panic!();
        }
        next
    }
}

基本上,如果可能的话R引发 panic 和 T有析构函数,您将进入未定义的行为,因为数组的元素可能并未在该阶段全部初始化。 Box<T>是此类未定义行为的一个特别好的例子,因为您将尝试释放未定义的内存地址。

这就是为什么这样的数组使用需要(a)有一个长度成员来显示数组中有多少项有数据,以便您可以跳过其余项的析构函数(这将需要更多不安全的代码当然,目前原生不支持简单地禁用析构函数),或者 (b) 用 Option 包装每个项目。 ,将未初始化的值设置为 None这样非法值的析构函数就不会被运行。

或者(c)你可以使用向量。

目前,固定大小的数组在 Rust 中是二等公民。

关于rust - 让编译器相信数组的每个索引都将被初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30383934/

相关文章:

rust - 是否可以在模式中创建可变引用的可变值?

generics - 返回通用 lambda 时为 "Ambiguous associated type"

vector - 如何通过将 Option 向量中的项目转换为 None 来过滤它们?

rust - 如果大小写不匹配,如何反序列化枚举?

rust - 为什么我会收到有关非详尽模式的错误消息?

import - 如何使用条件编译对 Rust 中的导入进行分组?

rust - 使用 const 通过强制转换来计算其他 const 表达式

hashmap - 如何为我自己的结构实现 Eq 和 Hash 以将它们用作 HashMap 键?

rust - Rust 文档中的 "Clone works only for going from &T to T"是什么意思?

parsing - 在 Rust 语言中将 String 解析为 Unsigned 的问题