Outside of main, you cannot use let
bindings.
error: expected item, found keyword `let`
--> src/âŚ
|
5 | let mut con: Vec<f64> = [18.0,13.0,8.0,0.32,0.36,0.31];
| ^^^ expected item
|
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
As the full error message is pointing out, âexpected itemâ is referring to the syntactical notion of an âitemâ as defined in the reference.
More concretely, the kind of items youâll be interested in for defining some global value/variable will be static
and const
. Letâs not discuss the difference between those two in detail here; but both do have in common that their (initial) value must be a âconstantâ, evaluated at compile-time. And compile-time evaluation wonât support allocating a Vec
:
static CON: Vec<f64> = vec![18.0,13.0,8.0,0.32,0.36,0.31];
error[E0010]: allocations are not allowed in statics
--> src/âŚ
|
5 | static CON: Vec<f64> = vec![18.0,13.0,8.0,0.32,0.36,0.31];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics
|
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: cannot call non-const fn `slice::<impl [f64]>::into_vec::<std::alloc::Global>` in statics
--> src/âŚ
|
5 | static CON: Vec<f64> = vec![18.0,13.0,8.0,0.32,0.36,0.31];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
A general solution can be to define a global value in a static
variable that is initialized lazily, lifting the need to do (or other disallowed operations) allocations at compile-time. Since recently, the relevant wrapper type, now called LazyLock
, is even part of the standard library (and youâll see it mentioned in the compiler error above):
use std::sync::LazyLock;
static CON: LazyLock<Vec<f64>> = LazyLock::new(|| vec![18.0,13.0,8.0,0.32,0.36,0.31]);
However, for lists of constants, it is usually a nicer approach to just avoid Vec
and allocations entirely; as other answers already demonstrated, using [f64; 6]
or &[f64]
can be a good and simple solution here.