Timmmm
Timmmm

Reputation: 96586

Can array lengths be inferred in Rust?

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

Answers (4)

mkrieger1
mkrieger1

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

Chayim Friedman
Chayim Friedman

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

miedzinski
miedzinski

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

Francis Gagné
Francis Gagné

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

Related Questions