如何在数组开头添加一个值?我知道怎样将两个数组连接起来,但如果我有一个数组和一个单独的值(与数组中的类型相同),我能把这个元素添加到数组的开头吗?
在稳定版的Rust中无法实现这一点;数组无法在运行时添加或删除值;它们的长度在编译时固定。
更可能的是,您想使用Vec
和Vec::insert
。
另请参见:
// 1.52.0-nightly (2021-03-07 234781afe33d3f339b00)
#![allow(incomplete_features)]
#![feature(const_generics, const_evaluatable_checked)]
use std::{
array::IntoIter,
mem::{self, MaybeUninit},
ptr,
};
fn prepend<T, const N: usize>(a: [T; N], v: T) -> [T; N + 1] {
// # SAFETY
//
// Converting an uninitialized array to an array of
// uninitialized values is always safe.
// https://github.com/rust-lang/rust/issues/80908
let mut xs: [MaybeUninit<T>; N + 1] = unsafe { MaybeUninit::uninit().assume_init() };
let (head, tail) = xs.split_first_mut().unwrap();
*head = MaybeUninit::new(v);
for (x, v) in tail.iter_mut().zip(IntoIter::new(a)) {
*x = MaybeUninit::new(v)
}
// # SAFETY
//
// We are effectively transmuting from an array of filled `MaybeUninit<T>` to
// the array of `T`, but cannot actually use `transmute`:
// https://github.com/rust-lang/rust/issues/61956
unsafe {
let tmp_xs = &mut xs as *mut [MaybeUninit<T>; N + 1] as *mut [T; N + 1];
mem::forget(xs);
ptr::read(tmp_xs)
}
}
fn main() {
let v = prepend([1, 2, 3], 4);
assert_eq!([4, 1, 2, 3], v);
}
另请参阅:
let arr1: [T; num]; let arr2: [T; num + 1];
- Brandon Dyeruse phpify::array::array_unshift;
let mut queue = vec!["orange", "banana"];
array_unshift(&mut queue, "apple");
assert_eq!(queue, vec!["apple", "orange", "banana"]);
Reference:https://docs.rs/phpify/0.1.0-beta4/phpify/array/index.html
另一种方法是在Rust中编写一个类似于https://stackoverflow.com/a/8963973/9676346的函数。
Vec
而不是数组),无缘无故地使用了一个库,而简单的 Vec::insert()
就可以解决问题,这个库根本不常用;另外还有更好的答案。 - Chayim Friedman
Arr
类型,分配N
个元素,然后每次想要添加东西时重新创建一个大小为N+1
的数组...或者你可以停止试图避免使用Vec
,它已经管理了所有这些,并且不能更好地完成(嗯,也许设计为允许在前面和后面插入大量元素并通过在它们周围保留“填充内存”的元素来保持中间元素的向量在某些情况下会更好,尽管此时最好使用列表)在我们现在拥有的计算机上。 - user11877195