在 Rust 中,是否可以使用模式匹配从
[T; k]
的第一个 k
元素构造 [T; n]
?我想避免这种情况:
// k = 3 here
let [c1, c2, c3, ..] = my_array;
let front = [c1, c2, c3];
而是做这样的事情(虚构的语法):
let front: [T; 3];
[..front, ..] = my_array;
// or...
let [..front: [T; 3], ..] = my_array;
// or...
let [front @ [_; 3], ..] = my_array;
这样的事情可能吗?
如果
T
是复制的,你可以轻松做到:
let front: [T; 3] = my_array[..3].try_into().unwrap();
如果
T
不是Copy
但是有便宜的Clone
,你也可以这么做:
let front: [T; 3] = <&[T; 3]>::try_from(&my_array[..3]).unwrap().clone();
如果不是(克隆很昂贵或者
T
不是Clone
),您可以通过分配来实现:
let front = my_array.into_iter().take(3).collect::<Vec<T>>();
let front: [T; 3] = front.try_into().unwrap();
Iterator::next_chunk()
:
#![feature(iter_next_chunk)]
let front: [T; 3] = my_array.into_iter().next_chunk().unwrap();
最后,如果没有什么足够的,你可以使用不安全的代码来做到这一点(但这实际上应该是最后的手段):
use std::mem::ManuallyDrop;
pub fn front<T, const N: usize, const M: usize>(arr: [T; N]) -> [T; M] {
assert!(M <= N);
let mut arr = ManuallyDrop::new(arr);
unsafe {
let result: [T; M] = arr.as_ptr().cast::<[T; M]>().read();
let rest = arr.as_mut_ptr().add(M);
let rest_len = N - M;
let rest = std::ptr::slice_from_raw_parts_mut(rest, rest_len);
rest.drop_in_place();
result
}
}