Reputation: 96586
I can do this:
let a: [f32; 3] = [0.0, 1.0, 2.0];
But why doesn't this work?
let a: [f32; _] = [0.0, 1.0, 2.0];
It seems to me that the length is redundant and trivial to infer. Is there a way to avoid having to specify it explicitly? (And without having to append f32
to all the literals.)
Upvotes: 27
Views: 4900
Reputation: 23144
If you are dealing with constants or static variables (and you have to specify the type) it's common to use a slice type instead:
static FOO: &[f32] = &[0.0, 1.0, 2.0];
This was originally a comment by Lukas Kalbertodt to another answer.
Upvotes: 4
Reputation: 70950
It is now possible on nightly with the generic_arg_infer
feature, for both the type and the initializer:
#![feature(generic_arg_infer)]
let _arr: [f32; _] = [0.0, 1.0, 2.0];
let _arr: [f32; 3] = [0.0; _];
Upvotes: 7
Reputation: 113
Since 1.39 it's possible using a simple macro
macro_rules! arr {
($id: ident $name: ident: [$ty: ty; _] = $value: expr) => {
$id $name: [$ty; $value.len()] = $value;
}
}
Usage
arr!(static BYTES: [u8; _] = *b"foo");
arr!(let floats: [f32; _] = [0., 1.]);
Upvotes: 7
Reputation: 65742
_
can only be used in two contexts: in patterns, to match a value to ignore, and as a placeholder for a type. In array types, the length is not a type, but an expression, and _
cannot be used in expressions.
What you can do, though, is append f32
to only one of the literals and omit the type completely. Since all the items of an array must have the same type, the compiler will infer the correct element type for the array.
let a = [0.0f32, 1.0, 2.0];
Upvotes: 34