gpt4 book ai didi

arrays - 如何创建和初始化不可变数组?

转载 作者:行者123 更新时间:2023-11-29 08:04:21 24 4
gpt4 key购买 nike

我想创建一个数组。我不需要数组是可变的,并且在创建时,我拥有计算数组第 i 个成员所需的所有信息。但是,无法弄清楚如何在 Rust 中创建不可变数组。

这是我现在拥有的:

let mut my_array: [f32; 4] = [0.0; 4];
for i in 0..4 {
// some calculation, doesn't matter what exactly
my_array[i] = some_function(i);
}

这就是我想要的:

let my_array: [f32; 4] = array_factory!(4, some_function);

我如何在 Rust 中实现它?

最佳答案

这是带有示例用法的宏定义:

macro_rules! array_factory(
($size: expr, $factory: expr) => ({
unsafe fn get_item_ptr<T>(slice: *mut [T], index: usize) -> *mut T {
(slice as *mut T).offset(index as isize)
}

let mut arr = ::std::mem::MaybeUninit::<[_; $size]>::uninit();
unsafe {
for i in 0..$size {
::std::ptr::write(get_item_ptr(arr.as_mut_ptr(), i), $factory(i));
}
arr.assume_init()
}
});
);

fn some_function(i: usize) -> f32 {
i as f32 * 3.125
}

fn main() {
let my_array: [f32; 4] = array_factory!(4, some_function);
println!("{} {} {} {}", my_array[0], my_array[1], my_array[2], my_array[3]);
}

宏的主体基本上是您的第一个版本,但有一些变化:

  • 省略了数组变量的类型注解,因为它可以推断。
  • 数组创建时未初始化,因为无论如何我们都将立即覆盖所有值。处理未初始化的内存是不安全的,因此我们必须在 unsafe block 中对其进行操作。在这里,我们使用 MaybeUninit ,它在 Rust 1.36 中被引入以取代 mem::uninitialized 1.
  • 使用 std::ptr::write() 分配项目由于数组未初始化的事实。赋值会尝试在数组中删除一个未初始化的值;效果取决于数组项类型(对于实现 Copy 的类型,如 f32,它没有效果;对于其他类型,它可能会崩溃)。
  • 宏主体是一个 block 表达式(即用大括号括起来),该 block 以一个没有后跟分号的表达式结尾,arr.assume_init()。因此,该 block 表达式的结果是 arr.assume_init()

我们可以制作这个宏的安全版本,而不是使用不安全的功能;但是,它要求数组项类型实现 Default特征。请注意,我们必须在此处使用正常赋值,以确保正确删除数组中的默认值。

macro_rules! array_factory(
($size: expr, $factory: expr) => ({
let mut arr = [::std::default::Default::default(), ..$size];
for i in 0..$size {
arr[i] = $factory(i);
}
arr
});
)

1 这是有充分理由的。此答案的先前版本使用了 mem::uninitialized,不是内存安全的:如果在初始化数组时发生 panic (因为工厂函数 panic ),并且数组的项目类型有析构函数,编译器将插入代码以在数组中的每个项目上调用析构函数;甚至还没有初始化的项目! MaybeUninit 避免了这个问题,因为它将正在初始化的值包装在 ManuallyDrop 中。 ,这是 Rust 中的一种魔法类型,可以防止析构函数自动运行。

关于arrays - 如何创建和初始化不可变数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26435046/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com