Rust macros for array and Vec
literals with superpowers.
The macro for arrays is called arr!
; the macro for Vec
is called vec!
and shadows the macro from the standard library.
They allow creating an array or Vec
where only some elements are specified,
and the rest is set to a default value:
rust
let a = arr![1, 2, 3; default: 0; 8];
assert_eq!(a, [1, 2, 3, 0, 0, 0, 0, 0]);
You can also specify elements at specific array indices:
rust
let a = arr![default: 1, 6: 0; 8];
assert_eq!(a, [1, 1, 1, 1, 1, 1, 0, 1]);
You can even specify the first n elements as well as specific indices:
rust
let a = arr![1, 2; default: 3, 6: 0; 8];
assert_eq!(a, [1, 2, 3, 3, 3, 3, 0, 3]);
They also support normal array syntax (arr![a; N]
and arr![a, b, c]
). This means that
the vec!
macro from this crate is a drop-in replacement for std::vec!
.
Copy
bound and default valuesUnless the literal specifies all elements explicitly (e.g. arr![1, 2, 3]
), the
type in the array or Vec
must implement the Copy
trait, and the literal must
specify a default value.
The macros generate a block that first creates a array or Vec
, and then
inserts the specified values:
rust
arr![default: 4, 0: 0, 1: 1; 5]
// is expanded to
{
let mut arr = [4; 5]; // in the vec! macro, std::vec! is used
arr[0] = 0;
arr[1] = 1;
arr
}
In trivial cases such as arr![3; 5]
, the 'static
lifetime is inferred for array
literals. This means that they have the exact same behavior as normal array literals.
In the other cases, the 'static
lifetime is not inferred. This means that the
array literal is computed at runtime and doesn't have a fixed memory location.
It also means that the following
rust
// does NOT compile!
fn return_temporary() -> &'static [i32; 4] {
&arr![default: 0, 0: 1; 4]
}
produces error[E0515]: cannot return reference to temporary value
. This can be solved
by assigning the literal to a const
or static
variable first:
rust
fn return_temporary() -> &'static [i32; 4] {
static ARR: &[i32; 4] = &arr![default: 0, 0: 1; 4];
ARR
}
Note that const
enforces const evaluation, which means that the whole array is
included in the application binary. This might not be desirable if the array is large.
When positional elements are combined with elements at specific indices, the positional elements are assigned first, so they might be overwritten later:
rust
let a = arr![1, 2; default: 1, 0: 0; 4];
assert_eq!(a, [0, 2, 1, 1]);
If you use the 2018 edition, import the macros with
rust
use array_lit::{arr, vec};
If you don't want to shadow std::vec!
, you can rename the macro:
rust
use array_lit::{arr, vec as vector};
If you're on the 2015 edition, or want to import the macros globally, you can add this to your crate root instead:
```rust
extern crate array_lit; ```
no_std
supportThis library supports no_std
, if default features are disabled.
This makes the vec!
macro unavailable.
This library supports the macros in const
and static
contexts since
Rust 1.33. Without them, Rust 1.30 is supported (but 1 doc-test fails).
Licensed under MIT or Apache 2.0 at your choice.