【问题标题】:Fixed array initialization without implementing Copy or Default trait修复了未实现 Copy 或 Default trait 的数组初始化
【发布时间】:2021-06-03 13:06:59
【问题描述】:

我想制作一个将在 for 循环中初始化的 2D 固定大小数组。这是示例代码(Cell 结构由于某种原因无法实现 Copy 或 Default trait):

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);
    }
}

但是编译器给出了这个错误:

使用可能未初始化的变量

所以为了确保编译器我的数组至少完全初始化了 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]

然后编译器给出这个错误:

特征绑定[maze_maker::Cell; 20]: std::marker::Copy不满足

特征 std::marker::Copy 没有为 [maze_maker::Cell; 20] 实现

注意:Copy trait 是必需的,因为重复的元素将被复制

我该怎么办):?

【问题讨论】:

  • 非常感谢,但是有点复杂,部分还使用了不安全的代码
  • 迭代初始化数组的常用方法是使用天生不安全的Maybeuninit。如果你保证结果被完全初始化,它是完全安全的(尽管它包含一个不安全的块)
  • 所以这可能是我真正的答案!谢谢你,小伙伴。我很感激你?????????
  • 或者,根据您的性能限制(或缺乏),您可以创建一个Vec(或多个vecs),然后尝试convert to a fixed size array。不过,使用一维存储后端可能会更简单,在两遍中转换内部 vecs 和外部 vecs 会相当复杂,而且分配成本有点高。

标签: arrays rust initialization traits


【解决方案1】:

如果你不介意临时分配,你可以利用 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();

如果您对外部 crate 没问题,您可以调整上述内容以使用 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();

另一方面,如果您已经在使用外部 crate,那么其他答案推荐的 array_init crate 可能更合适。

【讨论】:

    【解决方案2】:

    array_init crate 在这里可以帮助你,它允许你创建一个数组,方法是给它一个重复调用的函数,或者收集一个迭代器。

    【讨论】:

      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      相关资源
      最近更新 更多