我正在编写占用64字节块的代码,并且我想在类型级别上强制使用此大小:
i
但是,数据以切片fn f(buf: &[u8; 64]) { ... }
的形式进入。因此,我希望能够使用此子空间并将其转换为&[u8]
。事实证明,以下转换有效:
&[u8; 64]
但是以下内容却没有:
let buf = (0..32).collect::<Vec<u8>>();
let z: &[u8; 32] = &(&buf[..]).try_into().unwrap();
从0到32(包括0和32)之间的差异,该转换有效,但对于32以上的尺寸无效。如何执行此let buf = (0..64).collect::<Vec<u8>>();
let z: &[u8; 64] = &(&buf[..]).try_into().unwrap();
-> &[u8]
转换而无需手动执行数据复制? / p>
答案 0 :(得分: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(()))
}
}