我有一个特征,它为其实现者指定了一个反序列化函数。此特征应采用固定大小的数组,u8
该数组的长度取决于实现者(例如,类型A
可能从 10 个字节开始反序列化,类型B
可能从 50 个字节开始反序列化)。不幸的是,当我希望它支持实现我的特征的类型的数组的反序列化时,我无法让此特征工作,我总是遇到与泛型在 const 表达式中不可用相关的错误。需要注意的一件重要事情是,我的代码在一个非常特殊的环境中运行,我需要在编译时知道我的 calldata 的大小,所以Vec
很遗憾,我无法将其切换出来并完成它。这是我到目前为止尝试过的方法:
尝试 1:
trait MyTrait {
const ARR_LEN: usize;
fn deserialize<const N: usize>(array: [u8; N]) -> Self;
}
impl<const M: usize, T> MyTrait for [T; M]
where
T: MyTrait,
{
const ARR_LEN: usize = M * T::ARR_LEN;
fn deserialize<const N: usize>(array: [u8; N]) -> Self {
array
.chunks_exact(T::ARR_LEN)
.map(|chunk| T::deserialize::<{T::ARR_LEN}>(chunk.try_into().unwrap()))
.collect::<Vec<_>>()
.try_into()
.unwrap()
}
}
这会导致反序列化函数部分出现错误T::deserialize::<{T::ARR_LEN}>
,即我们不能在 const 表达式中使用泛型类型。
尝试2:
trait MyTrait {
const ARR_LEN: usize;
fn deserialize(array: [u8; Self::ARR_LEN]) -> Self;
}
impl<const M: usize, T> MyTrait for [T; M]
where
T: MyTrait,
{
const ARR_LEN: usize = M * T::ARR_LEN;
fn deserialize(array: [u8; ARR_LEN]) -> Self {
array
.chunks_exact(T::ARR_LEN)
.map(|chunk| T::deserialize(chunk.try_into().unwrap()))
.collect::<Vec<_>>()
.try_into()
.unwrap()
}
}
这会导致部分错误fn deserialize(array: [u8; ARR_LEN]) -> Self {
,另外,我不能在 const 表达式中使用泛型(因为ARR_LEN
是使用构造的T::ARR_LEN
)。
尝试3:
trait MyTrait {
const ARR_LEN: usize;
type ArrayType: Sized;
fn deserialize(array: Self::ArrayType) -> Self;
}
impl<const M: usize, T> MyTrait for [T; M]
where
T: MyTrait,
{
const ARR_LEN: usize = M * T::ARR_LEN;
type ArrayType = [u8; Self::ARR_LEN];
fn deserialize(array: Self::ArrayType) -> Self {
array
.chunks_exact(T::ARR_LEN)
.map(|chunk| T::deserialize(chunk.try_into().unwrap()))
.collect::<Vec<_>>()
.try_into()
.unwrap()
}
}
这会导致部分错误type ArrayType = [u8; Self::ARR_LEN]
,如上所述,我不能在 const 表达式中使用泛型(因为这里也是ARR_LEN
使用构造的T::ARR_LEN
)。
有谁对我如何才能让它工作有想法或不同的方法(而不必诉诸使用夜间版#![feature(generic_const_exprs)]
)?