rust 将“轴”向量创建为编译时常量

ippsafx7  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(128)

给定一个用于图形或线性代数的相当简单的“小向量”结构:

pub struct VecN<T, const N: usize>
{
    v: [T; N],
}

如何将典型的“轴”向量创建为 * 编译时 * 常量?例如,沿着于以下内容的内容:

impl<T> VecN<T, 3> where T: From<f32> + Default
{
    const AXES: [VecN<T, 3>; 3] = [VecN::new([T::from(1.0), T::default(), T::default()]),
                                   VecN::new([T::default(), T::from(1.0), T::default()]),
                                   VecN::new([T::default(), T::default(), T::from(1.0)])];
}

(The由于无法在编译时计算From和Default特性,因此上述方法无效。)
最好的情况是,我找到的唯一“变通方法”是为我感兴趣的每种类型创建常量,例如,

impl VecN<f32, 3>
{
    const AXES: [VecN<T, 3>; 3] = [VecN::new([1.0, 0.0, 0.0]),
                                   VecN::new([0.0, 1.0, 0.0]),
                                   VecN::new([0.0, 0.0, 1.0])];
}

这感觉非常多余,即使它可以很容易地使用宏来缓解。当然,更奇异的类型不包括在内。有没有什么方法可以使它以更通用的方式工作?

zf9nrax1

zf9nrax11#

正如你所提到的,这里的问题是trait方法不能在编译时求值。然而,* 可以 * 在编译时求值的是trait constants,所以你可以定义一个trait,其中包含ZEROONE的常量,并使用它们来代替:

trait ConstNum {
    const ZERO: Self;
    const ONE: Self;
}

impl ConstNum for f32 { .. }
impl ConstNum for f64 { .. }
// etc

impl<T: ConstNum> VecN<T, 3> {
    const AXES: [VecN<T, 3>; 3] = [VecN::new([T::ONE, T::ZERO, T::ZERO]),
                                   VecN::new([T::ZERO, T::ONE, T::ZERO]),
                                   VecN::new([T::ZERO, T::ZERO, T::ONE])];
}

相关问题