如何使用函数初始化数组? [英] How can I initialize an array using a function?
问题描述
我想在 Rust 中创建一个包含 10 个空向量的数组,但是 [Vec::new();10]
不起作用,因为 Vec
没有实现 Copy
.我怎样才能做到这一点,更一般地说,我怎样才能通过重复调用一个函数来初始化一个数组?
I want to create an array of 10 empty vectors in Rust, but [Vec::new(); 10]
doesn't work as Vec
doesn't implement Copy
. How can I do this, and in more general terms how can I initialize a array by repeatedly calling a function?
推荐答案
我看到两种可能的方法
第一
使用宏的简单解决方案
macro_rules! array {
($v: expr; 1) => ([$v]);
($v: expr; 2) => ([$v, $v]);
($v: expr; 3) => ([$v, $v, $v]);
($v: expr; 4) => ([$v, $v, $v, $v]);
($v: expr; 5) => ([$v, $v, $v, $v, $v]);
// until 32
}
let a = array![Vec::new(); 3];
有点冗长,但即使是 标准库使用这种结构.
It's a bit verbose, but even the standard library uses this kind of construct.
第二
After realizing a connection between this question and another that I had answered before, I wrote this solution using nodrop
extern crate nodrop;
macro_rules! array {
($e: expr; $n:expr) => (
{
use std::mem;
use std::ptr;
use nodrop::NoDrop;
struct ArrayBuilder<T> {
len: usize,
data: *mut T,
}
impl<T> Drop for ArrayBuilder<T> {
fn drop(&mut self) {
unsafe {
while self.len > 0 {
let offset = (self.len as isize) - 1;
self.len -= 1;
ptr::drop_in_place(self.data.offset(offset));
}
}
}
}
let mut v: NoDrop<[_; $n]> = NoDrop::new(unsafe {
mem::uninitialized()
});
// helps type inference for v
if false { v[0] = $e; }
let mut builder = ArrayBuilder {
len: 0,
data: (&mut *v as *mut _) as *mut _
};
unsafe {
for i in 0..$n {
ptr::write(builder.data.offset(i as isize), $e);
builder.len = i + 1;
}
}
builder.len = 0;
v.into_inner()
}
)
}
let a = array![Vec::new(); 3];
还有一个测试,表明它不会泄漏内存
And a test that indicates that it does not leak memory
#[test]
fn test() {
static mut COUNT: usize = 0;
#[derive(Debug)]
struct X(usize);
impl Drop for X {
fn drop(&mut self) {
println!("drop {:?}", self.0);
}
}
impl X {
fn new() -> X {
unsafe {
if COUNT == 3 {
panic!();
}
let x = X(COUNT);
COUNT += 1;
x
}
}
}
array![X::new(); 6];
}
在这个测试中,方法X::new
在创建X(3)
时发生panic,所以X(0)
,X(1)
, X(2)
必须删除.
In this test, the method X::new
panics when creating X(3)
, so X(0)
, X(1)
, X(2)
must be dropped.
其他
这篇关于如何使用函数初始化数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!