arrays - 如何声明一个结构数组并稍后对其进行初始化?
问题描述
我有一个结构:
struct Point {
x: u32,
y: u32,
}
我想Point
在两个不同的变量中有两个 s。我想先声明它们,然后再初始化。它适用于单独的值:
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()
};
}
也可以看看:
推荐阅读
- html - 图像的引导列不会内联
- android - 华硕触摸屏显示器和安卓设备的问题
- selenium - 将参数传递给 Junit 5 TestRunner 扩展
- regex - 正则表达式逐位输入十进制数
- scala - spark-rdbms :覆盖模式的工作方式与 Append 不同
- android - Android FirebaseAuth 未记录的`getAccessToken`
- python - 后期变量绑定的后期代码评估?
- r - rapply“替换”行为不符合预期
- regex - 如何从 Windows 命令行 grep 输出
- google-apps-script - Strava api 与 Google oauth2 库。状态令牌未正确返回或 Google oauth2 库未正确处理它