Array of structs, quick like C

In Rust you have to put the variables and the name of the struct in each array element.

In C you just put the literals.

const v0: i8 = 0;
const v1: i8 = 1;
const v2: i8 = 2;
const v3: i8 = 3;

struct Arr {
v: i8,
s: &'static str,
}

const str: [Arr; 4] = [
Arr {
v: v0,
s:"zero",
},
Arr {
v: v1,
s:"one",
},
Arr {
v: v2,
s:"two",
},
Arr {
v: v3,
s:"three",
},
];

fn main() {
println!("{}", str[2].v);
}

I think this sould be fixed.

Please read the pinned formatting guide.

Being able to elide the struct name has been suggested from time to time.

I don't think there is anything to fix. I also don't think it's a particularly common issue. But anyway, there are several ways to do it shorter, depending on the amount of boilerplate you're willing to write and on your use case.

let s: [Arr; 4] = [
    (v0, "zero"),
    (v1, "one"),
    (v2, "two"),
    (v3, "three"),
].map(|(v, s)| Arr { v, s });

This is the simplest way to construct an array of structs. Unfortunately, it cannot currently be used to create a const, because the map method on arrays isn't const (and due to implementation details, likely won't be const for a long time).

macro_rules! arr {
    ($({ $v: expr, $s: expr }),* $(,)?) => {
        [
            $(Arr { v: $v, s: $s }),*
        ]
    };
}

const s: [Arr; 4] = arr![
    { v0, "zero" },
    { v1, "one" },
    { v2, "two" },
    { v3, "three" },
];

The macro-based approach works in any context, and you can use whatever syntax you like. Defining the macro is slightly verbose, though. Depending on how common such arrays are in your code, this could be the best approach. You could also write a more complex macro, which could handle arbitrary structs (personally I consider it an overkill).

6 Likes

Thx @afetisov, great answer.
An other way is to find a nice snip, that converts csv to an array of structs.
If someone has it available let it show to us.

The main documentation for the csv crate has an example for doing exactly this...

1 Like