Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to default-initialize a struct containing an array in Rust?

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?

like image 609
Andrew Wagner Avatar asked Nov 21 '14 13:11

Andrew Wagner


People also ask

How do you initialize an array in Rust?

If you need an array initialized with the same value repeated for each element, and the type of value contained in the array implements the Copy trait, Rust supports a shorthand syntax shown above. let _: [u8; 3] = [rng. gen(); 3]; One important thing to note from this example is that the copy happens after the rng.

How do you initialize an entire array with value?

Initializer List: To initialize an array in C with the same value, the naive way is to provide an initializer list. We use this with small arrays. int num[5] = {1, 1, 1, 1, 1}; This will initialize the num array with value 1 at all index.

How array can be initialized by initializer method?

There are two ways to specify initializers for arrays: With C89-style initializers, array elements must be initialized in subscript order. Using designated initializers, which allow you to specify the values of the subscript elements to be initialized, array elements can be initialized in any order.


1 Answers

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.

like image 123
Matthieu M. Avatar answered Sep 22 '22 01:09

Matthieu M.