由 const 泛型表达式限定的方法不满足特征限定

Method bounded by a const generic expression does not satisfy trait bound

我目前正在按照 Jamis Buck 的“The Ray Tracer Challenge”一书实施光线追踪器。

我已经到了必须在矩阵上实现一些方法的部分,并且由于这些矩阵的编译时大小已知,我选择使用 const generics expressions 来实现它们(这仍然只是在夜间频道上可用)。

#![feature(generic_const_exprs)]

Matrix类型定义如下:

#[derive(Debug)]
pub struct Matrix<const N: usize>(pub [[f64; N]; N]);

我实现了以下方法:

impl<const N: usize> Matrix<N> {
    fn submatrix(&self, index: Idx) -> Matrix<{ N - 1 }> {
        //...
    }

    fn minor(&self, index: Idx) -> f64
    where
        [(); N - 1]:,
    {
        let submatrix = self.submatrix(index);
        submatrix.determinant()
    }

    fn cofactor(&self, index: Idx) -> f64
    where
        [(); N - 1]:,
    {
        let minor = self.minor(index);
        //...
    }

    fn determinant(&self) -> f64
    where
        [(); N - 1]:,
    {
        //...
    }
}

...但是我 运行 遇到了 submatrix 方法的问题,returns 一个 Matrix<{ N - 1 }>.

submatrix 上调用 determinant 方法时,这就是我们在 minor 方法中所做的:

fn minor(&self, index: Idx) -> f64
    where
        [(); N - 1]:,
    {
        let submatrix: Matrix<{ N - 1 }> = self.submatrix(index);
        submatrix.determinant()
    }

... 即使 minor 方法受以下约束约束:

where [(); N - 1]:,

...编译器仍然抱怨并建议添加相同的 where bound using this expression:

error: unconstrained generic constant
   --> src/rt/matrix.rs:109:19
    |
109 |         submatrix.determinant()
    |                   ^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); N - 1]:`
note: required by a bound in `Matrix::<N>::determinant`
   --> src/rt/matrix.rs:128:14
    |
126 |     fn determinant(&self) -> f64
    |        ----------- required by a bound in this
127 |     where
128 |         [(); N - 1]:,
    |              ^^^^^ required by this bound in `Matrix::<N>::determinant`

我试图为 Matrix<{ N - 1 }> 实现 minor 方法,但它似乎也不起作用(或者更确切地说,我不知道该怎么做,或者甚至不知道该怎么做):

impl<const N: usize> Matrix<{ N - 1 }> {
    fn minor(&self, index: Idx) -> f64 {
        let submatrix = self.submatrix(index);
        submatrix.determinant()
    }

... 出现以下错误:

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
   --> src/rt/matrix.rs:138:12
    |
138 | impl<const N: usize> Matrix<{ N - 1 }> {
    |            ^ unconstrained const parameter
    |
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported

我想知道我在这里用 submatrix 尝试做的事情是否可行。这没什么大不了的,因为我可以为每个可能的 N 定义这些方法,在我的例子中,这些方法仅限于 2_usize3_usize4_usize,但仅为 [=33] 实现这些方法=] 会干净很多!

警告: generic_const_exprs 功能 不稳定!不要在生产中使用它!


您在 submatrix 上调用 determinant(),它已经是 Matrix<{ N - 1 }>(从 submatrix() 返回)。所以你也可以将它限制为 where [(); N - 1 - 1]:,(请注意,Rust 编译器不够聪明,无法理解这与 where [(); N - 2]:, 相同,也无法得出结论,如果这也成立,那么 where [(); N - 1]:,。你必须同时写:where [(); N - 1]:, [(); N - 1 - 1]:,):

    fn minor(&self, index: Idx) -> f64
    where
        [(); N - 1]:,
        [(); N - 1 - 1]:,
    {
        let submatrix = self.submatrix(index);
        submatrix.determinant()
    }

    fn cofactor(&self, index: Idx) -> f64
    where
        [(); N - 1]:,
        [(); N - 1 - 1]:,
    {
        let minor = self.minor(index);
        //...
    }