Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I turn a GenericArray<T, ?> into an array of the same length?

I'm computing the SHA256 of a given data:

let hashvalue = sha2::Sha256::digest(&data);

After computing it, I want to put this value into a field of my struct:

let x = Hash { value: hashvalue };

However, the Hash struct expects the type of value [u8; 32], while my hashvalue variable is of type GenericArray<u8, ?>. How can I convert hashvalue into the correct type? I tried to use as [u8; 32] and arr! but it didn't work.

like image 763
Ziva Avatar asked Dec 17 '19 14:12

Ziva


People also ask

Can you make an array of generics in Java?

Java allows generic classes, methods, etc. that can be declared independent of types. However, Java does not allow the array to be generic. The reason for this is that in Java, arrays contain information related to their components and this information is used to allocate memory at runtime.

Why can't you make a generic array in Java?

Arrays of generic types are not allowed because they're not sound. The problem is due to the interaction of Java arrays, which are not statically sound but are dynamically checked, with generics, which are statically sound and not dynamically checked.

Are there any issues when combining generics and arrays?

You will find that a simple statement like this will not even compile because the Java compiler does not allow this. To understand the reason, you first need to know two arrays are covariant and generics are invariant. Because of this fundamental reason, arrays and generics do not fit well with each other.

What is the difference between an array and a generic array?

An important difference between arrays and generics is how they enforce type checking. Specifically, arrays store and check type information at runtime. Generics, however, check for type errors at compile-time and don't have type information at runtime. Java's syntax suggests we might be able to create a new generic array:

What does the second type parameter in genericarray<t> represent in generic_array?

The second type parameter in GenericArray<T, N> represents in some sense the length of the GenericArray. generic_array uses the types from the crate typenum by default (though with some effort, you could provide your own types — you'd just need to implement the necessary traits for them).

How do I implement a stack with a generic array?

As we'd like the stack to work with any type, a reasonable implementation choice would be a generic array. First, we'll create a field to store the elements of our stack, which is a generic array of type E: public MyStack(Class<E> clazz, int capacity) { elements = (E []) Array.newInstance (clazz, capacity); }

Is it possible to initialize generic arrays?

Although we can't initialize generic arrays directly, it's still possible to achieve the equivalent operation if the precise type of information is provided by the calling code. 3. Creating a Generic Array For our example, let's consider a bounded stack data structure, MyStack, where the capacity is fixed to a certain size.


1 Answers

If you don't know the length of the array, convert the GenericArray into a slice and then convert the slice into an array (only for arrays of length 32 or less before Rust 1.47):

use sha2::Digest; // 0.9.3
use std::convert::TryInto;

fn main() {
    let hashvalue = sha2::Sha256::digest(&[3, 2, 6, 4, 3]);
    let x: [u8; 32] = hashvalue.as_slice().try_into().expect("Wrong length");
    println!("{:?}", x);
}

See also:

  • How to get a slice as an array in Rust?
  • How to convert a slice into an array reference?
  • Is it possible to control the size of an array using the type parameter of a generic?
like image 53
Shepmaster Avatar answered Oct 15 '22 12:10

Shepmaster