Primitive Type array1.0.0[−]
Expand description
A fixed-size array, denoted [T; N]
, for the element type, T
, and the
non-negative compile-time constant size, N
.
There are two syntactic forms for creating an array:
- A list with each element, i.e.,
[x, y, z]
. - A repeat expression
[x; N]
, which produces an array withN
copies ofx
. The type ofx
must beCopy
.
Note that [expr; 0]
is allowed, and produces an empty array.
This will still evaluate expr
, however, and immediately drop the resulting value, so
be mindful of side effects.
Arrays of any size implement the following traits if the element type allows it:
Copy
Clone
Debug
IntoIterator
(implemented for[T; N]
,&[T; N]
and&mut [T; N]
)PartialEq
,PartialOrd
,Eq
,Ord
Hash
AsRef
,AsMut
Borrow
,BorrowMut
Arrays of sizes from 0 to 32 (inclusive) implement the Default
trait
if the element type allows it. As a stopgap, trait implementations are
statically generated up to size 32.
Arrays coerce to slices ([T]
), so a slice method may be called on
an array. Indeed, this provides most of the API for working with arrays.
Slices have a dynamic size and do not coerce to arrays.
You can move elements out of an array with a slice pattern. If you want
one element, see mem::replace
.
Examples
let mut array: [i32; 3] = [0; 3];
array[1] = 1;
array[2] = 2;
assert_eq!([1, 2], &array[1..]);
// This loop prints: 0 1 2
for x in array {
print!("{} ", x);
}
RunYou can also iterate over reference to the array’s elements:
let array: [i32; 3] = [0; 3];
for x in &array { }
RunYou can use a slice pattern to move elements out of an array:
fn move_away(_: String) { /* Do interesting things. */ }
let [john, roa] = ["John".to_string(), "Roa".to_string()];
move_away(john);
move_away(roa);
RunEditions
Prior to Rust 1.53, arrays did not implement IntoIterator
by value, so the method call
array.into_iter()
auto-referenced into a slice iterator. Right now, the old behavior
is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring
IntoIterator
by value. In the future, the behavior on the 2015 and 2018 edition
might be made consistent to the behavior of later editions.
let array: [i32; 3] = [0; 3];
// This creates a slice iterator, producing references to each value.
for item in array.into_iter().enumerate() {
let (i, x): (usize, &i32) = item;
println!("array[{}] = {}", i, x);
}
// The `array_into_iter` lint suggests this change for future compatibility:
for item in array.iter().enumerate() {
let (i, x): (usize, &i32) = item;
println!("array[{}] = {}", i, x);
}
// You can explicitly iterate an array by value using
// `IntoIterator::into_iter` or `std::array::IntoIter::new`:
for item in IntoIterator::into_iter(array).enumerate() {
let (i, x): (usize, i32) = item;
println!("array[{}] = {}", i, x);
}
RunStarting in the 2021 edition, array.into_iter()
will use IntoIterator
normally to iterate
by value, and iter()
should be used to iterate by reference like previous editions.
let array: [i32; 3] = [0; 3];
// This iterates by reference:
for item in array.iter().enumerate() {
let (i, x): (usize, &i32) = item;
println!("array[{}] = {}", i, x);
}
// This iterates by value:
for item in array.into_iter().enumerate() {
let (i, x): (usize, i32) = item;
println!("array[{}] = {}", i, x);
}
RunFuture language versions might start treating the array.into_iter()
syntax on editions 2015 and 2018 the same as on edition 2021. So code using
those older editions should still be written with this change in mind, to
prevent breakage in the future. The safest way to accomplish this is to
avoid the into_iter
syntax on those editions. If an edition update is not
viable/desired, there are multiple alternatives:
- use
iter
, equivalent to the old behavior, creating references - use
array::IntoIter
, equivalent to the post-2021 behavior (Rust 1.51+) - replace
for ... in array.into_iter() {
withfor ... in array {
, equivalent to the post-2021 behavior (Rust 1.53+)
use std::array::IntoIter;
let array: [i32; 3] = [0; 3];
// This iterates by reference:
for item in array.iter() {
let x: &i32 = item;
println!("{}", x);
}
// This iterates by value:
for item in IntoIter::new(array) {
let x: i32 = item;
println!("{}", x);
}
// This iterates by value:
for item in array {
let x: i32 = item;
println!("{}", x);
}
// IntoIter can also start a chain.
// This iterates by value:
for item in IntoIter::new(array).enumerate() {
let (i, x): (usize, i32) = item;
println!("array[{}] = {}", i, x);
}
RunImplementations
Returns an array of the same size as self
, with function f
applied to each element
in order.
If you don’t necessarily need a new fixed-size array, consider using
Iterator::map
instead.
Note on performance and stack usage
Unfortunately, usages of this method are currently not always optimized as well as they could be. This mainly concerns large arrays, as mapping over small arrays seem to be optimized just fine. Also note that in debug mode (i.e. without any optimizations), this method can use a lot of stack space (a few times the size of the array or more).
Therefore, in performance-critical code, try to avoid using this method
on large arrays or check the emitted code. Also try to avoid chained
maps (e.g. arr.map(...).map(...)
).
In many cases, you can instead use Iterator::map
by calling .iter()
or .into_iter()
on your array. [T; N]::map
is only necessary if you
really need a new array of the same size as the result. Rust’s lazy
iterators tend to get optimized very well.
Examples
let x = [1, 2, 3];
let y = x.map(|v| v + 1);
assert_eq!(y, [2, 3, 4]);
let x = [1, 2, 3];
let mut temp = 0;
let y = x.map(|v| { temp += 1; v * temp });
assert_eq!(y, [1, 4, 9]);
let x = ["Ferris", "Bueller's", "Day", "Off"];
let y = x.map(|v| v.len());
assert_eq!(y, [6, 9, 3, 3]);
Run‘Zips up’ two arrays into a single array of pairs.
zip()
returns a new array where every element is a tuple where the
first element comes from the first array, and the second element comes
from the second array. In other words, it zips two arrays together,
into a single one.
Examples
#![feature(array_zip)]
let x = [1, 2, 3];
let y = [4, 5, 6];
let z = x.zip(y);
assert_eq!(z, [(1, 4), (2, 5), (3, 6)]);
Runpub fn as_mut_slice(&mut self) -> &mut [T]ⓘ
pub fn as_mut_slice(&mut self) -> &mut [T]ⓘ
Returns a mutable slice containing the entire array. Equivalent to
&mut s[..]
.
Borrows each element and returns an array of references with the same
size as self
.
Example
#![feature(array_methods)]
let floats = [3.1, 2.7, -1.0];
let float_refs: [&f64; 3] = floats.each_ref();
assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
RunThis method is particularly useful if combined with other methods, like
map
. This way, you can avoid moving the original
array if its elements are not Copy
.
#![feature(array_methods)]
let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
let is_ascii = strings.each_ref().map(|s| s.is_ascii());
assert_eq!(is_ascii, [true, false, true]);
// We can still access the original array: it has not been moved.
assert_eq!(strings.len(), 3);
RunBorrows each element mutably and returns an array of mutable references
with the same size as self
.
Example
#![feature(array_methods)]
let mut floats = [3.1, 2.7, -1.0];
let float_refs: [&mut f64; 3] = floats.each_mut();
*float_refs[0] = 0.0;
assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
assert_eq!(floats, [0.0, 2.7, -1.0]);
RunTrait Implementations
The hash of an array is the same as that of the corresponding slice,
as required by the Borrow
implementation.
#![feature(build_hasher_simple_hash_one)]
use std::hash::BuildHasher;
let b = std::collections::hash_map::RandomState::new();
let a: [u8; 3] = [0xa8, 0x3c, 0x09];
let s: &[u8] = &[0xa8, 0x3c, 0x09];
assert_eq!(b.hash_one(a), b.hash_one(s));
RunCreates a consuming iterator, that is, one that moves each value out of
the array (from start to end). The array cannot be used after calling
this unless T
implements Copy
, so the whole array is copied.
Arrays have special behavior when calling .into_iter()
prior to the
2021 edition – see the array Editions section for more information.
type Item = T
type Item = T
The type of the elements being iterated over.
Implements comparison of arrays lexicographically.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more
type Error = TryFromSliceError
type Error = TryFromSliceError
The type returned in the event of a conversion error.
type Error = TryFromSliceError
type Error = TryFromSliceError
The type returned in the event of a conversion error.
type Error = TryFromSliceError
type Error = TryFromSliceError
The type returned in the event of a conversion error.
Gets the entire contents of the Vec<T>
as an array,
if its size exactly matches that of the requested array.
Examples
use std::convert::TryInto;
assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
RunIf the length doesn’t match, the input comes back in Err
:
use std::convert::TryInto;
let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
RunIf you’re fine with just getting a prefix of the Vec<T>
,
you can call .truncate(N)
first.
use std::convert::TryInto;
let mut v = String::from("hello world").into_bytes();
v.sort();
v.truncate(2);
let [a, b]: [_; 2] = v.try_into().unwrap();
assert_eq!(a, b' ');
assert_eq!(b, b'd');
RunAuto Trait Implementations
impl<T, const N: usize> RefUnwindSafe for [T; N] where
T: RefUnwindSafe,
impl<T, const N: usize> UnwindSafe for [T; N] where
T: UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more