固定数组初始化而不实现 Copy 或 Default 特性
Fixed array initialization without implementing Copy or Default trait
我想制作一个二维固定大小的数组,它将在 for 循环中初始化。这是示例代码(由于某些原因,Cell 结构无法实现 Copy 或 Default 特性):
let mut cells: [[Cell; 20]; 20];
for i in 0..20 {
for j in 0..20 {
cells[i][j] = Cell::new(some_value_based_on_i_and_j);
}
}
but then compiler gives this error:
使用可能未初始化的变量
所以为了向编译器保证我的数组至少被完全初始化了1次;我把它改成这样:
let mut cells: [[Cell; 20]; 20] = [[Cell::new(default_value); 20]; 20];
for i in 0..20 {
for j in 0..20 {
cells[i][j] = Cell::new(some_value_based_on_i_and_j);
}
}
(事实上,我想听编译器并使用类似这种模式的默认值初始化数组的所有索引,然后执行我之前的工作):
let a = [-12, 100] // means -> [default_value, repetition_or_also_length_of_the_array]
Then the compiler gives this error:
特征界限[maze_maker::Cell; 20]: std::marker::Copy
不满足
特征 std::marker::Copy
没有为 [maze_maker::Cell; 20]
实现
注意:Copy
trait 是必需的,因为重复的元素将被复制
我该怎么做):?
array_init
crate 在这里可能对您有所帮助,它可以让您创建一个数组,方法是给它一个将重复调用的函数,或者收集一个迭代器。
如果你不介意临时分配,你可以利用 Vec<T>
实现 TryInto<[T; N]>
的事实,如果 运行 的长度返回错误 Vec
不适合数组的大小。它不是特别优雅,但不需要不安全:
let cells: [[Cell<usize>; 20]; 20] = (0..20)
.map(|i| {
(0..20)
.map(|j| Cell::new(i + j))
.collect::<Vec<_>>()
.try_into()
.unwrap()
})
.collect::<Vec<_>>()
.try_into()
.unwrap();
如果您可以使用外部板条箱,您可以调整以上内容以使用 arrayvec
来避免分配:
let cells: [[Cell<usize>; 20]; 20] = (0..20)
.map(|i| {
(0..20)
.map(|j| Cell::new(i + j))
.collect::<ArrayVec<_, 20>>()
.into_inner()
.unwrap()
})
.collect::<ArrayVec<_, 20>>()
.into_inner()
.unwrap();
另一方面,如果您已经在使用外部包装箱,那么其他答案推荐的 array_init
包装箱可能更合适。
我想制作一个二维固定大小的数组,它将在 for 循环中初始化。这是示例代码(由于某些原因,Cell 结构无法实现 Copy 或 Default 特性):
let mut cells: [[Cell; 20]; 20];
for i in 0..20 {
for j in 0..20 {
cells[i][j] = Cell::new(some_value_based_on_i_and_j);
}
}
but then compiler gives this error:
使用可能未初始化的变量
所以为了向编译器保证我的数组至少被完全初始化了1次;我把它改成这样:
let mut cells: [[Cell; 20]; 20] = [[Cell::new(default_value); 20]; 20];
for i in 0..20 {
for j in 0..20 {
cells[i][j] = Cell::new(some_value_based_on_i_and_j);
}
}
(事实上,我想听编译器并使用类似这种模式的默认值初始化数组的所有索引,然后执行我之前的工作):
let a = [-12, 100] // means -> [default_value, repetition_or_also_length_of_the_array]
Then the compiler gives this error:
特征界限[maze_maker::Cell; 20]: std::marker::Copy
不满足
特征 std::marker::Copy
没有为 [maze_maker::Cell; 20]
注意:Copy
trait 是必需的,因为重复的元素将被复制
我该怎么做):?
array_init
crate 在这里可能对您有所帮助,它可以让您创建一个数组,方法是给它一个将重复调用的函数,或者收集一个迭代器。
如果你不介意临时分配,你可以利用 Vec<T>
实现 TryInto<[T; N]>
的事实,如果 运行 的长度返回错误 Vec
不适合数组的大小。它不是特别优雅,但不需要不安全:
let cells: [[Cell<usize>; 20]; 20] = (0..20)
.map(|i| {
(0..20)
.map(|j| Cell::new(i + j))
.collect::<Vec<_>>()
.try_into()
.unwrap()
})
.collect::<Vec<_>>()
.try_into()
.unwrap();
如果您可以使用外部板条箱,您可以调整以上内容以使用 arrayvec
来避免分配:
let cells: [[Cell<usize>; 20]; 20] = (0..20)
.map(|i| {
(0..20)
.map(|j| Cell::new(i + j))
.collect::<ArrayVec<_, 20>>()
.into_inner()
.unwrap()
})
.collect::<ArrayVec<_, 20>>()
.into_inner()
.unwrap();
另一方面,如果您已经在使用外部包装箱,那么其他答案推荐的 array_init
包装箱可能更合适。