我在初始化固定长度数组时遇到问题. 到目前为止,我的尝试都导致了"使用可能未初始化的变量:foo_array
"错误:
#[derive(Debug)]
struct Foo { a: u32, b: u32 }
impl Default for Foo {
fn default() -> Foo { Foo{a:1, b:2} }
}
pub fn main() {
let mut foo_array: [Foo; 10];
// Do something here to in-place initialize foo_array?
for f in foo_array.iter() {
println!("{:?}", f);
}
}
Run Code Online (Sandbox Code Playgroud)
error[E0381]: use of possibly uninitialized variable: `foo_array`
--> src/main.rs:13:14
|
13 | for f in foo_array.iter() {
| ^^^^^^^^^ use of possibly uninitialized `foo_array`
Run Code Online (Sandbox Code Playgroud)
我实现了Default
特性,但Rust似乎并没有像默认情况下那样调用C++构造函数.
初始化固定长度数组的正确方法是什么?我想做一个有效的就地初始化而不是某种副本.
A.B*_*.B. 20
安全但效率低下的解决方案:
#[derive(Copy, Clone, Debug)]
struct Foo {
a: u32,
b: u32,
}
fn main() {
let mut foo_array = [Foo { a: 10, b: 10 }; 10];
}
Run Code Online (Sandbox Code Playgroud)
由于您特别要求没有副本的解决方案:
use std::{mem, ptr};
#[derive(Debug)]
struct Foo {
a: u32,
b: u32,
}
// We're just implementing Drop to prove there are no unnecessary copies.
impl Drop for Foo {
fn drop(&mut self) {
println!("Destructor running for a Foo");
}
}
pub fn main() {
let array = unsafe {
// Create an uninitialized array.
let mut array: [Foo; 10] = mem::uninitialized();
for (i, element) in array.iter_mut().enumerate() {
let foo = Foo { a: i as u32, b: 0 };
// Overwrite `element` without running the destructor of the old value.
// Since Foo does not implement Copy, it is moved.
ptr::write(element, foo)
}
array
};
for element in array.iter() {
println!("{:?}", element);
}
}
Run Code Online (Sandbox Code Playgroud)
Ibr*_*med 11
最简单的方法是派生Copy
您的类型并用它初始化数组,复制元素N
时间:
#[derive(Copy)]
struct Foo {
a: u32,
b: u32,
}
let mut foo_array = [Foo { a: 1, b: 2 }; 10];
Run Code Online (Sandbox Code Playgroud)
如果您想避免复制,有几个选择。您可以使用该Default
特征:
let mut foo_array: [Foo; 10] = Default::default();
Run Code Online (Sandbox Code Playgroud)
但是,这仅限于最多 32 个元素的数组。借助 const 泛型,标准库现在可以Default
为所有数组提供支持。然而,由于正在研究的微妙原因,这将是一个向后不兼容的更改。
现在,您可以利用const
数组重复表达式中也允许值的事实:
const FOO: Foo = Foo { a: 1, b: 2 };
let mut foo_array = [FOO; 10];
Run Code Online (Sandbox Code Playgroud)
如果您每晚使用,您可以使用array::map
:
#![feature(array_map)]
let mut foo_array = [(); 10].map(|_| Foo::default())
Run Code Online (Sandbox Code Playgroud)
您可以使用arrayvec
板条箱:
货代
[package]
name = "initialize_array"
version = "0.1.0"
authors = ["author"]
edition = "2018"
[dependencies]
arrayvec = "0.4.10"
Run Code Online (Sandbox Code Playgroud)
src / main.rs
use arrayvec::ArrayVec;
use std::iter;
#[derive(Clone)]
struct Foo {
a: u32,
b: u32,
}
fn main() {
let foo_array: [Foo; 10] = iter::repeat(Foo { a: 10, b: 10 })
.collect::<ArrayVec<_>>()
.into_inner()
.unwrap_or_else(|_| unreachable!());
}
Run Code Online (Sandbox Code Playgroud)