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.
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.
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.
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.
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:
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).
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); }
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With