问题
What is the recommended way to declare a struct that contains an array, and then create a zero-initialized instance?
Here is the struct:
#[derive(Default)]
struct Histogram {
sum: u32,
bins: [u32; 256],
}
and the compiler error:
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`
If I attempt to add the missing initializer for the array:
impl Default for [u32; 256] {
fn default() -> [u32; 255] {
[0; 256]
}
}
I get:
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
Am I doing something wrong?
回答1:
Rust does not implement Default
for all arrays because it does not have non-type polymorphism. As such, Default
is only implemented for a handful of sizes.
You can, however, implement a default for your type:
impl Default for Histogram {
fn default() -> Histogram {
Histogram {
sum: 0,
bins: [0; 256],
}
}
}
Note: I would contend that implementing Default
for u32
is fishy to start with; why 0
and not 1
? or 42
? There is no good answer, so no obvious default really.
回答2:
I'm afraid you can't do this, you will need to implement Default
for your structure yourself:
struct Histogram {
sum: u32,
bins: [u32; 256],
}
impl Default for Histogram {
#[inline]
fn default() -> Histogram {
Histogram {
sum: 0,
bins: [0; 256],
}
}
}
Numeric types have nothing to do with this case, it's more like problems with fixed-size arrays. They still need generic numerical literals to support this kind of things natively.
回答3:
If you're sure to initialize every field with zero, this would work:
impl Default for Histogram {
fn default() -> Histogram {
unsafe { std::mem::zeroed() }
}
}
回答4:
Indeed, at the time of writing, support for fixed-length arrays is still being hashed out in the standard library:
https://github.com/rust-lang/rust/issues/7622
来源:https://stackoverflow.com/questions/27062874/how-to-default-initialize-a-struct-containing-an-array-in-rust