如何将&[u8]转换为&[u8; 64]?

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

我正在编写需要64字节块的代码,并且我想在类型级别上强制使用此大小:

fn f(buf: &[u8; 64]) { ... }

但是,数据作为切片&[u8]进入。因此,我希望能够使用此子空间并将其转换为&[u8; 64]。事实证明,以下转换有效:

let buf = (0..64).collect::<Vec<u8>>();
let z: &[u8; 32] = &(&buf[..]).try_into().unwrap();

但是以下内容不是:

let buf = (0..64).collect::<Vec<u8>>();
let z: &[u8; 64] = &(&buf[..]).try_into().unwrap();

差异在0到32之间(包括0和32),该转换有效,但对于32以上的尺寸无效。我可以做些什么来启用此&[u8]-> &[u8; 64]转换而无需手动执行数据复制?

rust type-conversion
1个回答
1
投票

如果需要,可以将the code that Rust currently uses用于0-32尺寸。

#[stable(feature = "try_from", since = "1.34.0")]
impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]
where
    [T; N]: LengthAtMost32,
{
    type Error = TryFromSliceError;

    fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
        if slice.len() == N {
            let ptr = slice.as_ptr() as *const [T; N];
            unsafe { Ok(&*ptr) }
        } else {
            Err(TryFromSliceError(()))
        }
    }
}

当常量泛型稳定后,绑定的[T; N]: LengthAtMost32可能会被删除。在此之前,您可以实现自己的功能。晚上使用启用了常量泛型的函数,或者只是针对您的特定大小使用一个函数。

struct TryFromSliceError(());

fn slice_to_array_64<T>(slice: &[T]) -> Result<&[T; 64], TryFromSliceError> {
    if slice.len() == 64 {
        let ptr = slice.as_ptr() as *const [T; 64];
        unsafe {Ok(&*ptr)}
    } else {
        Err(TryFromSliceError(()))
    }
}

(playground)

© www.soinside.com 2019 - 2024. All rights reserved.