Add elements of data type to array (or similar)

I'm using data types (PubKey and PrivKey) from a library and create them in a loop with constant indices 1..NUM_INSTANCES.

const NUM_INSTANCES: usize = 32;

Those types don't have any default initialization.

I create elements of those types and wanna add those to an array or ArrayVec.

1. via Array

let mut private_keys: [PrivKey<Sha256_256>; NUM_INSTANCES];

I can add thee elements inside the loop into the array, e.g.:

priv_keys[idx-1] = priv_key;

But if I try to use those elements later in a loop the following way as an argument to a function:

&priv_keys[idx-1].as_slice()

then I get the following (of course correct) message:

used binding priv_keys isn't initialized

I don't think I can initialize an array properly. I could create fake keys and try to add them in a loop to initialize the array...

2. via ArrayVec

Another approach was to use an ArrayVec:

let mut priv_keys: ArrayVec<[PrivKey<Sha256_256>; NUM_INSTANCES]>;

and push() the created elements after creating:

priv_keys.push(priv_key);

but that yielded the following message:

the method `push` exists for struct `ArrayVec<[PrivKey<Sha256_256>; 32]>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`[my_lib::PrivKey<my_lib::Sha256_256>; 32]: Array`

I don't really understand this message...I can't find anything regarding a trait Array:

My questions

  • I'd like to understand the message with the "trait bounds"
  • Any ideas what's a good way to achieve what I wanna do, assuming that I can't change the types PrivKey and PubKey?

I think proper invocation should be

let mut priv_keys: ArrayVec<PrivKey<Sha256_256>, NUM_INSTANCES>;

You do have to initialize an array all at once. But perhaps you can replace your loop with std::array::from_fn()?

Another approach was to use an ArrayVec … I can't find anything regarding a trait Array

There are several libraries containing an ArrayVec type, and probably that library also defines an Array trait. Which one do you mean?

1 Like

Generally the way I'm declaring it also works (copy & paste from existing code), but I'll probably change it then to the documented approach.

You do have to initialize an array all at once. But perhaps you can replace your loop with std::array::from_fn()?

Thanks -- I'll have to look into that.

There are several libraries containing an ArrayVec type, and probably that library also defines an Array trait. Which one do you mean?

Seems you're right, I didn't think of looking there:

I see. tinyvec and arrayvec are two different crates implementing similar but slightly different structures.

1 Like

tinyvec's main documentation:

The limitation is that the element type of a vec from this crate must support the Default trait. This means that this crate isn’t suitable for all situations, but a very surprising number of types do support Default.

So, you can't use tinyvec::ArrayVec without Default. You could use arrayvec::ArrayVec instead.

1 Like

Nice, that seems to do the trick!

I'm having another problem with my code, but I assume that's nothing to do with the arrays that are getting constructed with this function.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.