gpt4 book ai didi

arrays - 如何声明一个结构数组并稍后对其进行初始化?

转载 作者:行者123 更新时间:2023-12-03 11:44:22 24 4
gpt4 key购买 nike

我有一个结构:

struct Point {
x: u32,
y: u32,
}

我想在两个不同的变量中有两个 Point。我想先声明它们,然后再初始化。它适用于单独的值:

let p0: Point;
let p1: Point;

p0 = Point { x: 1, y: 2 };
p1 = Point { x: 2, y: 3 };

我想用数组做同样的事情:

let p: [Point; 2];

p[0] = Point { x: 1, y: 2 };
p[1] = Point { x: 2, y: 3 };

无法正常工作,因为出现编译错误:

error[E0381]: use of possibly-uninitialized variable: `p`
--> src/main.rs:9:5
|
9 | p[0] = Point { x: 1, y: 2 };
| ^^^^ use of possibly-uninitialized `p`

为什么它对单个变量和数组的行为不同?我可以不使用 Default::default() 吗?

最佳答案

Rust 要求数组中的每个元素都被初始化。编译器实际上无处可跟踪每个值的初始化状态。

手动方法涉及使用不安全的 Rust 代码与 MaybeUninit 配对和原始指针操作。然后程序员负责正确维护所有要求:

use std::{mem::MaybeUninit, ptr};

#[derive(Debug)]
struct Point {
x: u32,
y: u32,
}

fn main() {
// I copied this code from Stack Overflow without reading
// the prose that describes why this is or is not safe.
let p = unsafe {
// Future: MaybeUninit::uninit_array
let mut p = MaybeUninit::<[Point; 2]>::uninit();

// Future: MaybeUninit::first_ptr_mut
let h = p.as_mut_ptr() as *mut Point;
ptr::write(h.offset(0), Point { x: 1, y: 2 });
ptr::write(h.offset(1), Point { x: 2, y: 3 });

p.assume_init()
};
}

程序员必须在调用 assume_init 之前验证所有元素都已填充,否则代码具有未定义的行为。

相反,使用 ArrayVec 更容易,它为您处理所有不安全的逻辑:

use arrayvec::ArrayVec; // 0.5.1

struct Point {
x: u32,
y: u32,
}

fn main() {
let p = {
let mut p = ArrayVec::<[Point; 2]>::new();

p.insert(0, Point { x: 1, y: 2 });
p.insert(1, Point { x: 2, y: 3 });

p.into_inner()
};
}

另见:

关于arrays - 如何声明一个结构数组并稍后对其进行初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64885448/

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