Primitive Type array1.0.0[−]
Expand description
一个固定大小的数组,表示为 [T; N]
,用于元素类型 T
和非负编译时常量大小, N
.
创建数组有两种语法形式:
- 每个元素的列表,即
[x, y, z]
. - 重复表达式
[x; N]
,该数组生成包含x
的N
副本的数组。x
的类型必须为Copy
。
请注意,[expr; 0]
是允许的,并产生一个空数组。
然而,这仍然会计算 expr
,并立即丢弃结果值,因此请注意副作用。
如果元素类型允许,则 any 大小的数组将实现以下 traits:
Copy
Clone
Debug
IntoIterator
(为[T; N]
、&[T; N]
和&mut [T; N]
实现)PartialEq
,PartialOrd
,Eq
,Ord
Hash
AsRef
,AsMut
Borrow
,BorrowMut
如果元素类型允许,则大小为 0 到 32 (inclusive) 的数组将实现 Default
trait。
作为权宜之计,trait 实现是静态生成的,最大大小为 32。
数组强制转换为 slices ([T]
) ,因此可以在数组上调用 slice 方法。实际上,这提供了用于处理数组的大多数 API。
切片具有动态大小,并且不强制转换为数组。
您可以使用 slice pattern 将元素移出数组。如果需要一个元素,请参见 mem::replace
。
Examples
let mut array: [i32; 3] = [0; 3]; array[1] = 1; array[2] = 2; assert_eq!([1, 2], &array[1..]); // 该循环打印: 0 1 2 for x in array { print!("{} ", x); }Run
您还可以迭代数组元素的引用:
let array: [i32; 3] = [0; 3]; for x in &array { }Run
您可以使用 slice pattern 将元素移出数组:
fn move_away(_: String) { /* Do interesting things. */ } let [john, roa] = ["John".to_string(), "Roa".to_string()]; move_away(john); move_away(roa);Run
Editions
在 Rust 1.53 之前,数组没有通过值实现 IntoIterator
,因此该方法调用 array.into_iter()
自动引用到切片迭代器中。
现在,为了兼容性,旧的行为被保留在 2015 和 2018 年版本的 Rust 中,忽略了 IntoIterator
的值。
将来,2015 年和 2018 年版本的行为可能会与以后版本的行为一致。
let array: [i32; 3] = [0; 3]; // 这将创建一个切片迭代器,产生对每个值的引用。 for item in array.into_iter().enumerate() { let (i, x): (usize, &i32) = item; println!("array[{}] = {}", i, x); } // `array_into_iter` lint 建议进行此更改以实现未来兼容性: for item in array.iter().enumerate() { let (i, x): (usize, &i32) = item; println!("array[{}] = {}", i, x); } // 您可以使用 `IntoIterator::into_iter` 或 `std::array::IntoIter::new` 按值显式迭代数组: for item in IntoIterator::into_iter(array).enumerate() { let (i, x): (usize, i32) = item; println!("array[{}] = {}", i, x); }Run
从 2021 年版开始,array.into_iter()
通常会使用 IntoIterator
按值迭代,iter()
应该像以前的版本一样用于按引用迭代。
let array: [i32; 3] = [0; 3]; // 这通过引用进行迭代: for item in array.iter().enumerate() { let (i, x): (usize, &i32) = item; println!("array[{}] = {}", i, x); } // 这是按值迭代的: for item in array.into_iter().enumerate() { let (i, x): (usize, i32) = item; println!("array[{}] = {}", i, x); }Run
未来的语言版本可能会开始将 2015 和 2018 版的 array.into_iter()
语法与 2021 版相同。
因此,在编写使用这些旧版本的代码时仍应牢记这一更改,以防止将来出现破坏。
实现这一点最安全的方法是避免这些版本中的 into_iter
语法。
如果版本更新不是不可行/不理想,则有多种选择:
- 使用
iter
,相当于旧行为,创建引用 - 使用
array::IntoIter
,相当于 2021 年后的行为 (Rust 1.51+) - 替换
for .... in array.into_iter() {
和for ... in array {
,相当于 2021 年后的行为 (Rust 1.53+)
use std::array::IntoIter; let array: [i32; 3] = [0; 3]; // 这通过引用进行迭代: for item in array.iter() { let x: &i32 = item; println!("{}", x); } // 这是按值迭代的: for item in IntoIter::new(array) { let x: i32 = item; println!("{}", x); } // 这是按值迭代的: for item in array { let x: i32 = item; println!("{}", x); } // IntoIter 也可以启动一个链。 // 这是按值迭代的: for item in IntoIter::new(array).enumerate() { let (i, x): (usize, i32) = item; println!("array[{}] = {}", i, x); }Run
Implementations
返回大小与 self
相同的数组,并将函数 f
按顺序应用于每个元素。
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
返回包含整个数组的可变切片。
等效于 &mut s[..]
。
借用每个元素,并返回一个引用数组,其大小与 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]);Run
如果与其他方法 (例如 map
) 结合使用,则此方法特别有用。
这样,如果原始数组的元素不是 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]); // 我们仍然可以访问原始数组: 它尚未移动。 assert_eq!(strings.len(), 3);Run
Trait Implementations
数组的哈希值与对应的 X 像素的哈希值相同,符合实现的要求。
#![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));Run
如果存在,则此方法返回 self
和 other
值之间的顺序。 Read more
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
如果 Vec<T>
的大小与请求的数组的大小完全匹配,则以数组的形式获取 Vec<T>
的全部内容。
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([]));Run
如果长度不匹配,则输入以 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]));Run
如果只需要获得 Vec<T>
的前缀就可以了,您可以先调用 .truncate(N)
。
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');Run