首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Rust中将切片作为数组获取?

如何在Rust中将切片作为数组获取?
EN

Stack Overflow用户
提问于 2014-08-21 22:25:39
回答 6查看 60.9K关注 0票数 83

我有一个未知大小的数组,我想获取该数组的一部分,并将其转换为静态大小的数组:

fn pop(barry: &[u8]) -> [u8; 3] {
    barry[0..3] // expected array `[u8; 3]`, found slice `[u8]`
}

我该怎么做呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2018-04-29 04:48:20

您可以很容易地使用TryInto特征(已在Rust1.34中稳定)来完成此操作:

use std::convert::TryInto;

fn pop(barry: &[u8]) -> [u8; 3] {
    barry.try_into().expect("slice with incorrect length")
}

但更好的是:不需要克隆/复制您的元素!实际上,可以从&[u8]获取&[u8; 3]

fn pop(barry: &[u8]) -> &[u8; 3] {
    barry.try_into().expect("slice with incorrect length")
}

正如在其他答案中提到的,如果barry的长度不是3,您可能不想惊慌,而是优雅地处理这个错误。

这要归功于相关特征TryFrom的这些隐含(在Rust 1.47之前,这些隐含只存在于长度不超过32的数组中):

impl<'_, T, const N: usize> TryFrom<&'_ [T]> for [T; N]
where
    T: Copy, 

impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]

impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]
票数 112
EN

Stack Overflow用户

发布于 2016-06-07 22:36:08

多亏了@malbarbo,我们可以使用这个帮助器函数:

use std::convert::AsMut;

fn clone_into_array<A, T>(slice: &[T]) -> A
where
    A: Default + AsMut<[T]>,
    T: Clone,
{
    let mut a = A::default();
    <A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
    a
}

要获得更简洁的语法:

fn main() {
    let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    let e = Example {
        a: clone_into_array(&original[0..4]),
        b: clone_into_array(&original[4..10]),
    };

    println!("{:?}", e);
}

T: Default + Clone一样长。

如果你知道你的类型实现了Copy,你可以使用下面的形式:

use std::convert::AsMut;

fn copy_into_array<A, T>(slice: &[T]) -> A
where
    A: Default + AsMut<[T]>,
    T: Copy,
{
    let mut a = A::default();
    <A as AsMut<[T]>>::as_mut(&mut a).copy_from_slice(slice);
    a
}

如果目标数组和传入的片不具有相同的长度,则这两个变体都将panic!

票数 21
EN

Stack Overflow用户

发布于 2014-08-21 22:55:58

下面是一个与您请求的类型签名相匹配的函数。

fn pop(barry: &[u8]) -> [u8; 3] {
    [barry[0], barry[1], barry[2]]
}

但是,由于barry的元素可能少于三个,因此您可能希望返回Option<[u8; 3]>而不是[u8; 3]

fn pop(barry: &[u8]) -> Option<[u8; 3]> {
    if barry.len() < 3 {
        None
    } else {
        Some([barry[0], barry[1], barry[2]])
    }
}
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25428920

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档