我正在尝试初始化一些可以为空的非可复制类型的固定大小的数组,就像Option<Box<Thing>>某种类型的那样Thing.我想把它们中的两个打包成一个没有任何额外间接的结构.我想写这样的东西:
let array: [Option<Box<Thing>>; SIZE] = [None; SIZE];
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为[e; n]语法要求e实现Copy.当然,我可以将它扩展为SIZE Nones,但是当SIZE它很大时,这可能是笨重的.我不相信这可以用没有非自然编码的宏来完成SIZE.有没有好办法呢?
是的,这很容易unsafe; 没有办法unsafe吗?
Tho*_*att 29
从 Rust 1.55.0(引入了[T]::map())开始,以下内容将起作用:
const SIZE: usize = 100;
#[derive(Debug)]
struct THING { data: i64 }
let array = [(); SIZE].map(|_| Option::<THING>::default());
for x in array {
println!("x: {:?}", x);
}
Run Code Online (Sandbox Code Playgroud)
rns*_*tlr 11
您可以使用Default特征来使用默认值初始化数组:
let array: [Option<Box<Thing>>; SIZE] = Default::default();
Run Code Online (Sandbox Code Playgroud)
有关工作示例,请参阅此游乐场.
use*_*342 10
从 Rust 1.38(于 2019 年 9 月发布)开始,可以使用中间const初始化程序为现有答案提供更清晰的替代方案。这种方法适用于任何大小的数组:
const SIZE: usize = 100;
const INIT: Option<Box<Thing>> = None;
let array: [Option<Box<Thing>>; SIZE] = [INIT; SIZE];
Run Code Online (Sandbox Code Playgroud)
(无论是否使用Box; 都可以使用;示例Box之所以使用,是因为在问题中使用了它。)
一个限制是数组项必须具有可以在编译时评估的默认表示 - 常量、枚举变体或由这些组成的原始容器。None或一组数字会起作用,但非空Vec或String不会。
我正在复制chris-morgan 的答案并对其进行调整以更好地匹配问题,遵循 dbaupp downthread 的建议,并匹配最近的语法更改:
use std::mem;
use std::ptr;
#[derive(Debug)]
struct Thing {
number: usize,
}
macro_rules! make_array {
($n:expr, $constructor:expr) => {{
let mut items: [_; $n] = mem::uninitialized();
for (i, place) in items.iter_mut().enumerate() {
ptr::write(place, $constructor(i));
}
items
}}
}
const SIZE: usize = 50;
fn main() {
let items = unsafe { make_array!(SIZE, |i| Box::new(Some(Thing { number: i }))) };
println!("{:?}", &items[..]);
}
Run Code Online (Sandbox Code Playgroud)
注意unsafe这里需要使用:问题是如果构造函数panic!是s,这会导致未定义的行为。
| 归档时间: |
|
| 查看次数: |
2684 次 |
| 最近记录: |