如何在 Rust 中默认初始化包含数组的结构体?

问题描述 投票:0回答:5

声明包含数组的结构,然后创建零初始化实例的推荐方法是什么?

这是结构:

#[derive(Default)]
struct Histogram {
    sum: u32,
    bins: [u32; 256],
}

和编译器错误:

error[E0277]: the trait bound `[u32; 256]: std::default::Default` is not satisfied
 --> src/lib.rs:4:5
  |
4 |     bins: [u32; 256],
  |     ^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `[u32; 256]`
  |
  = help: the following implementations were found:
            <[T; 14] as std::default::Default>
            <&'a [T] as std::default::Default>
            <[T; 22] as std::default::Default>
            <[T; 7] as std::default::Default>
          and 31 others
  = note: required by `std::default::Default::default`

如果我尝试为数组添加缺少的初始值设定项:

impl Default for [u32; 256] {
    fn default() -> [u32; 255] {
        [0; 256]
    }
}

我得到:

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
 --> src/lib.rs:7:5
  |
7 |     impl Default for [u32; 256] {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
  |
  = note: the impl does not reference any types defined in this crate
  = note: define and implement a trait or new type instead

我做错了什么吗?

arrays struct rust initializer
5个回答
16
投票

Rust 不会为所有数组实现

Default
,因为它不具有非类型多态性。因此,
Default
仅适用于少数尺寸。

但是,您可以为您的类型实现默认值:

impl Default for Histogram {
    fn default() -> Histogram {
        Histogram {
            sum: 0,
            bins: [0; 256],
        }
    }
}

注意:我认为为

Default
实现
u32
一开始就很可疑;为什么是
0
而不是
1
?还是
42
?没有好的答案,所以确实没有明显的默认值。


6
投票

恐怕你不能这样做,你需要自己为你的结构实现

Default

struct Histogram {
    sum: u32,
    bins: [u32; 256],
}

impl Default for Histogram {
    #[inline]
    fn default() -> Histogram {
        Histogram {
            sum: 0,
            bins: [0; 256],
        }
    }
}

数字类型与这种情况无关,它更像是固定大小数组的问题。他们仍然需要通用的数字文字来原生支持此类事物。


4
投票

如果您确定将每个字段都初始化为零,那么这会起作用:

impl Default for Histogram {
    fn default() -> Histogram {
        unsafe { std::mem::zeroed() }
    }
}

1
投票

事实上,在撰写本文时,标准库中仍在讨论对固定长度数组的支持:

https://github.com/rust-lang/rust/issues/7622


0
投票

如果数组类型不是

Copy
,则由@MatthieuM 回答。行不通的。在这种情况下,您可以使用
std::array::from_fn()
:

,而不是显式指定每个元素(这对于通用数组来说是乏味的甚至不可能的)
impl Default for Histogram {
    fn default() -> Histogram {
        Histogram {
            sum: Default::default(),
            bins: std::array::from_fn(|_| Default::default()),
        }
    }
}

如果您愿意,您也可以使用

array::map()
来完成:

impl Default for Histogram {
    fn default() -> Histogram {
        Histogram {
            sum: Default::default(),
            bins: [(); 256].map(|()| Default::default()),
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.