5

Any help here would be greatly appreciated.

The rust code below populates an array with default Foo values, up to N elements. I wish to do the same thing without having to explicitly code the Foo elements. That would obviously be unreasonable for large values of N (1K to 1M, or even more).

My primary goal is speed so I wish to avoid using vectors.

Also, I would like to avoid unsafe code blocks. If I must use unsafe, then the simpler the better for obvious reasons. ( I tend to think that if unsafe is required, then it should be a very high priority call for an improvement to rust-lang to change this. Therefore I would like the code easily modified to take advantage of such a hypothetical future version of rust. )

Again, I really appreciate experienced input here. If this is indeed a problem area in the language I think the answer(s) provided here would be very important to pin down. If there are references or links then please share!

struct Foo {
    abc: String,
    def: u32,
}

const N : usize = 2;

fn main() {
    let foo: [Foo; N] = [
        Foo{
            abc: "default".to_string(),
            def: 0,
        },
        Foo{
            abc: "default".to_string(),
            def: 0,
        },
    ];
    
    for bar in foo.iter() {
        println!("bar.abc={}, bar.def={}", bar.abc, bar.def);
    }
}
ChrisK
  • 61
  • 3
  • Also: [Initialize a large, fixed-size array with non-Copy types](https://stackoverflow.com/questions/28656387/initialize-a-large-fixed-size-array-with-non-copy-types) – Ibraheem Ahmed Apr 29 '21 at 15:32
  • 1
    Specifically from those questions, [this answer](https://stackoverflow.com/a/66776497/189205) gives the simplest solution that doesn't require `Copy` types. – interjay Apr 29 '21 at 16:06
  • @interjay I'm not sure that answer can be applied to the `Foo` type as defined here: `const INIT: Foo = Foo::default()` complains that "calls in constants are limited to constant functions, tuple structs and tuple variants". `const INIT: Foo = Foo { ... }` fails the same way (because of `to_string()`). Attempting to create a `const fn` that returns a `Foo` fails with the equivalent error message about "calls in constant _functions_". – user4815162342 Apr 29 '21 at 17:06
  • @user4815162342 You're right, I didn't notice the `String` default value which makes this method unusable in this case. It can be used if you want the string to be empty, because `String::new` is a constant function. – interjay Apr 29 '21 at 17:20
  • All the answers are covered in those 2 questions, this should be closed as a duplicate – Ibraheem Ahmed Apr 29 '21 at 21:38
  • So if you can't use a `Copy`/`Clone` solution, or `const` blocks, want to avoid `unsafe`, and need `N > 32`, you can use `arrayvec` or nightly with `array_map` as described in the linked answer. – Ibraheem Ahmed Apr 30 '21 at 15:25
  • Thank you all for the nice replies. I think there are new answers here that are not included in the other question, which is close. – ChrisK May 01 '21 at 13:24

0 Answers0