Hacker News new | ask | show | jobs
by rom-antics 1203 days ago
If you want compact, use an array of tuples:

  const foos = [("foo", 1, "bar"), ("foo", 1, "bar"), ...];
  for (str1, num, str2) in &foos {
      // ...
  }
For a proper struct you have to name the fields, because otherwise refactoring the fields could cause struct instances to silently get out of sync with the definition.
1 comments

>otherwise refactoring the fields could cause struct instances to silently get out of sync with the definition.

Having to name the fields is only part of the pain. You also have to redundantly repeat the struct name. I don't see any fundamental reason why something like this shouldn't be valid:

    let foo: [MyStruct; _] = [{a: "foo", b: 1, c: "amp"}, {a: "bar", b: 1, c: "fff"}, {a: "amp", b: 1, c: "aaa"} ];
I can see the logic for insisting on field names. However, the builtin 'go vet' tool has a nice behavior where it will flag the use of unkeyed literals for public structs only. This strikes me as a good compromise between concision and safety.
You can use map() to turn an array of tuples into an array of structures. Unfortunately at time of writing the optimiser doesn't do a great job on this, so if you're making an array of several thousand of something, or an array of things which are themselves very large, this might have unacceptable performance, but in cases where I have say a modest N values and I want N structures based on those values...

  fn make_struct(x: (&str, u8, &str)) -> MyStruct {
     MyStruct { a: x.0, b: x.1, c: x.2 }
  }

  let foo = [("foo", 1, "amp"), ("bar", 1, "fff"), ("amp", 1, "aaa")]
    .map(make_struct);
[I have not actually compiled this code, but it should do roughly what you meant]