Home > Net >  Rust more compact list initialisation?
Rust more compact list initialisation?

Time:08-15

I commonly have to work with geometric data, in C it was normal for me to do things like this:

struct Vertex { vec2;}
vector<Vertex> triangle = {{-1, 0}, {0,1}, {1, 0}};

Which is fairly convenient, especially if you start having more nested types, like adding more fields to Vertex.

In rust initializers need to be explicit, so i get things like this:

 let triangle : [Vertex; 3] = [
        Vertex{position : Vec2::new(-0.5, 0.0), color : Vec3::new(1.0, 0.0, 0.0)},
        Vertex{position : Vec2::new(0.0, 0.5), color : Vec3::new(0.0, 1.0, 0.0)},
        Vertex{position : Vec2::new(0.5, 0.0), color : Vec3::new(0.0, 0.0, 1.0)},
    ];

This is a little too much, it becomes tedious to specify the same fields over and over again, and this is not even that bad of a scenario, when you have position, normal and uv fields it becomes a mess.

Is there a way to initialise lists in a more compact way?

CodePudding user response:

You can simplify initialization, this is usually done by implementing From trait.

After that your code may look like

    let triangle : [Vertex; 3] = [
        ([-0.5, 0.0], [1.0, 0.0, 0.0]).into(),
        ([0.0, -0.5], [0.0, 1.0, 0.0]).into(),
        ([0.0, -1.0], [0.0, 1.0, 1.0]).into(),
    ];

Check a complete example here

Other way is to create fn new(x: f32, y: f32, c1: f32, c2: f32, c3: f32) -> Vertex:

impl Vertex {
    fn new(x: f32, y: f32, c1: f32, c2: f32, c3: f32) -> Vertex {
        Self {
            position: Vec2{x, y},
            color: Vec3{x: c1, y: c2, z: c3}
        }
    }
}
fn main() {
    let triangle : [Vertex; 3] = [
        Vertex::new(0.0, 0.1, 0.2, 0.3, 0.4),
        Vertex::new(0.1, 0.1, 0.2, 0.3, 0.4),
        Vertex::new(0.2, 0.1, 0.2, 0.3, 0.4),
    ];
}

CodePudding user response:

This may not be terse enough for you, but a very Rust-y pattern is the builder pattern. Your code could look like this:

let triangle: [Vertex; 3] = [
    Vertex::new().with_position(-0.5, 0.0).with_color(1.0, 0.0, 0.0),
    Vertex::new().with_position(0.0, 0.5).with_color(0.0, 1.0, 0.0),
    Vertex::new().with_position(0.5, 0.0).with_color(0.0, 0.0, 1.0),
];

Is this a lot shorter? No. Is it more convenient to write? I think so, but it's certainly subjective.

Full code

  • Related