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

问题描述 投票:0回答:1

在 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;

这样的事情可能吗?

arrays rust pattern-matching
1个回答
0
投票

如果

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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.