Rust模式匹配赋值:从`[T; n]`获取初始`[T; k]`

eufgjt7s  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(101)

在Rust中,是否可以使用模式匹配从[T; n]的第一个k元素构造[T; 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;


这种事有可能发生吗?

abithluo

abithluo1#

如果T是copy,你可以很容易地做到这一点:

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
    }
}

相关问题