gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:28:14 30 4
gpt4 key购买 nike

我正在编写采用 64 字节 block 的代码,我想在类型级别强制执行此大小:

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

但是,数据以切片 &[u8] 的形式传入。所以,我希望能够获取它的子空间并转换为 &[u8; 64]。事实证明,以下转换有效:

let buf = (0..32).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(含),转换有效,但不适用于 32 以上的尺寸。我该怎么做才能启用此 &[u8] -> &[u8; 64] 无需手动进行数据复制的转换?

最佳答案

如果需要,您可以使用 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(()))
}
}
}

当常量泛型稳定时,绑定(bind)的[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)

关于rust - 如何将 &[u8] 转换为 &[u8; 64]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58478116/

30 4 0