2

我有一个结构定义为:

use nalgebra::{
    allocator::Allocator, DefaultAllocator, Dim, DimName, MatrixN, RowVectorN, VectorN, U1,
}; // 0.22.0

pub struct Filter<Order: Dim + DimName>
where
    DefaultAllocator:
        Allocator<f64, Order, Order> + Allocator<f64, Order> + Allocator<f64, U1, Order>,
{
    a: MatrixN<f64, Order>,
    b: VectorN<f64, Order>,
    c: RowVectorN<f64, Order>,
    d: f64,
    x: VectorN<f64, Order>,
}

在我的单元测试模块中,我想构造一个实例Filter

mod tests {
    use super::*;
    use nalgebra::U2;

    fn a_filter() -> Filter<U2> {
        let a: MatrixN<f64, U2> = MatrixN::from_iterator([1., -0., 1., 0.].into_iter());

        Filter {
            a,
            b: VectorN::zeros(),
            c: RowVectorN::zeros(),
            d: 0.,
            x: VectorN::zeros()
        }
    }
}

调用MatrixN::from_iterator()导致编译错误。类似的错误发生在调用::zeros()

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:22:44
   |
22 |         let a: MatrixN<f64, U2> = MatrixN::from_iterator([1., -0., 1., 0.].into_iter());
   |                                            ^^^^^^^^^^^^^ multiple `from_iterator` found
   |
   = note: candidate #1 is defined in an impl for the type `nalgebra::Matrix<N, R, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, C>>::Buffer>`
   = note: candidate #2 is defined in an impl for the type `nalgebra::Matrix<N, R, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, nalgebra::Dynamic>>::Buffer>`
   = note: candidate #3 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, C>>::Buffer>`
   = note: candidate #4 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, nalgebra::Dynamic>>::Buffer>`

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:26:25
   |
26 |             b: VectorN::zeros(),
   |                         ^^^^^ multiple `zeros` found
   |
   = note: candidate #1 is defined in an impl for the type `nalgebra::Matrix<N, R, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, C>>::Buffer>`
   = note: candidate #2 is defined in an impl for the type `nalgebra::Matrix<N, R, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, nalgebra::Dynamic>>::Buffer>`
   = note: candidate #3 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, C>>::Buffer>`
   = note: candidate #4 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, nalgebra::Dynamic>>::Buffer>`

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:27:28
   |
27 |             c: RowVectorN::zeros(),
   |                            ^^^^^ multiple `zeros` found
   |
   = note: candidate #1 is defined in an impl for the type `nalgebra::Matrix<N, R, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, C>>::Buffer>`
   = note: candidate #2 is defined in an impl for the type `nalgebra::Matrix<N, R, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, nalgebra::Dynamic>>::Buffer>`
   = note: candidate #3 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, C>>::Buffer>`
   = note: candidate #4 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, nalgebra::Dynamic>>::Buffer>`

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:29:25
   |
29 |             x: VectorN::zeros(),
   |                         ^^^^^ multiple `zeros` found
   |
   = note: candidate #1 is defined in an impl for the type `nalgebra::Matrix<N, R, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, C>>::Buffer>`
   = note: candidate #2 is defined in an impl for the type `nalgebra::Matrix<N, R, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, nalgebra::Dynamic>>::Buffer>`
   = note: candidate #3 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, C>>::Buffer>`
   = note: candidate #4 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, nalgebra::Dynamic>>::Buffer>`

我不清楚为什么 Rust 无法找出正确from_iterator的使用方法。是因为我必须DefaultAllocator在定义中指定Filter吗?如果是这样,最干净的解决方法是什么?

4

1 回答 1

1

TL; 博士;您的代码的解决方法:

fn a_filter() -> Filter<U2> {
    let a = MatrixN::<f64, U2>::from_iterator([1.0, -0., 1., 0.].iter().copied());

    Filter {
        a,
        b: VectorN::<f64, U2>::zeros(),
        c: RowVectorN::<f64, U2>::zeros(),
        d: 0.,
        x: VectorN::<f64, U2>::zeros()
    }
}

您必须在调用中指定顺序,zeros()而不是从返回类型中猜测它。

有一个额外的from_iterator问题,array::into_iter()它不会返回对值的迭代器,而是对值的引用,就像iter()(是的,这很令人困惑,并且有一个 lint,IIRC),所以你需要添加 acopied()来获取正确的迭代器类型。


这是显示您的错误的最少代码(操场):

use nalgebra::{
    VectorN, U3
};
fn main() {
    let x: VectorN<f64, U3> = VectorN::zeros();
}

错误是:

error[E0034]: multiple applicable items in scope
 --> src/main.rs:5:40
  |
5 |     let x: VectorN<f64, U3> = VectorN::zeros();
  |                                        ^^^^^ multiple `zeros` found
  |
  = note: candidate #1 is defined in an impl for the type `nalgebra::Matrix<N, R, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, C>>::Buffer>`
  = note: candidate #2 is defined in an impl for the type `nalgebra::Matrix<N, R, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, R, nalgebra::Dynamic>>::Buffer>`
  = note: candidate #3 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, C, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, C>>::Buffer>`
  = note: candidate #4 is defined in an impl for the type `nalgebra::Matrix<N, nalgebra::Dynamic, nalgebra::Dynamic, <nalgebra::DefaultAllocator as nalgebra::allocator::Allocator<N, nalgebra::Dynamic, nalgebra::Dynamic>>::Buffer>`

如果您仔细查看候选人,他们只是以下人员的全名:

candidate #1: Matrix<N, R, C, _>
candidate #2: Matrix<N, R, Dynamic, _>`
candidate #3: Matrix<N, Dynamic, C, _>`
candidate #4: Matrix<N, Dynamic, Dynamic, _>`

所以他们与那Dynamic件事有关......如果您查看文档,它不是很有帮助,但是如果您查看zeros()函数中的示例,它会有提示:

let v = Vector3::<f32>::zeros();
let dv = DVector::<f32>::zeros(3);
let m = Matrix2x3::<f32>::zeros();
let dm = DMatrix::<f32>::zeros(2, 3);

等等...不是需要0个参数吗?好吧,看看代码,虽然文档没有说,但它看起来像在泛型类型中zeros()一样多的参数。DynamicAndVector3<T>是 的别名Vector<T, U3>DVector<T>是等的别名Vector<T, Dynamic>

您可能仍然认为编译器无论如何都可以推导出函数,因为每个版本的返回类型和参数编号都不同zero(),但这不是编译器的工作方式:Rust 中没有函数重载。如果一个函数名解析为多个函数,这是一个错误。

考虑这个显示类似错误的更简单的代码:

struct Foo<T> {
    t: T,
}

impl Foo<u8> {
    fn new() -> u8 {
        0
    }
}

impl Foo<u32> {
    fn new() -> u32 {
        0
    }
}

fn main() {
    let t: u8 = Foo::new(); // error!
}

请注意,如果两个函数返回相同或不同的类型,甚至它们是否具有相同数量的参数,这都无关紧要,这始终是编译器错误。

我的代码的解决方法是:

fn main() {
    let t: u8 = Foo::<u8>::new();
}
于 2020-09-15T20:09:13.610 回答