![](/img/trans.png)
[英]Rust error: unable to infer enough type information to locate the impl of the trait
[英]Rust unable to infer return type for generic trait impl
我又一次玩得很开心,试图满足 Rust 中的类型检查器。 这是我对即将出现的代码示例的模糊看法。 我有一个特征,它的方法需要一些 arguments,为了具有灵活性,我希望能够以任何可能的组合将参数设为特定类型,只要传入类型的关联类型实现给定的特征.
注意 trait 的类型参数A
和B
表示函数的输入。 现在我有一个版本,其中这些参数是函数的通用参数,但这不起作用,因为此 trait 的其他实现依赖于知道它需要哪些输入,因此它们必须是 trait generic 的一部分,并且它们不能移动下到泛型函数。
这是特征的样子:
pub trait Filter<T: Scalar + Lapack, A: Data<Elem=T>, B: Data<Elem=T>> {
type Prediction;
type Update;
fn predict(&self, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<B, Ix3>) -> Self::Prediction;
fn update(&self, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<A, Ix3>, measurements: &ArrayBase<A, Ix2>) -> Self::Update;
}
然后我有一个结构,它实现了这个特征,并且也不关心为特征方法提供哪些输入,只要它们的关联类型实现给定的特征,所以这是结构和 impl 的样子:
pub struct KalmanFilter<T: Scalar + Lapack> {
transition_matrix: Array2<T>,
observation_matrix: Array2<T>,
transition_covariance: Array2<T>,
observation_covariance: Array2<T>,
}
impl<T: Scalar + Lapack, A: Data<Elem=T>, B: Data<Elem=T>> Filter<T, A, B> for KalmanFilter<T> {
type Prediction = (ArrayBase<OwnedRepr<T>, Ix2>, ArrayBase<OwnedRepr<T>, Ix3>);
type Update = (ArrayBase<OwnedRepr<T>, Ix3>, ArrayBase<OwnedRepr<T>, Ix3>);
fn predict(&self, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<B, Ix3>) -> Self::Prediction {
......... code ..... code
}
fn update(
&self,
states: &ArrayBase<A, Ix2>,
covariances: &ArrayBase<A, Ix3>,
measurements: &ArrayBase<A, Ix2>,
) -> Self::Update {
......... code ..... code
}
现在我们来看看错误信息。 即当我尝试从上面的结构中调用更新方法时,我得到:
error[E0284]: type annotations needed: cannot satisfy `<_ as RawData>::Elem == f64`
--> src/filter/kalman.rs:320:20
|
320 | let a = kf.update(&states, &covariances, &measurements);
| ^^^^^^ cannot satisfy `<_ as RawData>::Elem == f64`
|
= note: required because of the requirements on the impl of `filter_traits::Filter<f64, OwnedRepr<f64>, _>` for `kalman::KalmanFilter<f64>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0284`.
error: could not compile `rusty_rudolf`
现在这很有趣,因为如果我手动进行单模化,并且基本上在 impl 块中,我将类型参数T
替换为f64
它就可以工作。 为什么这不起作用,为什么它适用于手动单态化?
编辑:还有一件事,如果我放弃将类型组合作为输入的能力,并且如果我在上面的特征中删除类型参数B
,它就会起作用。 不知何故,第二个类型参数的引入会导致问题。
问题可能出在第二个 function update()
上,它无法推断B
的类型,因为它没有引用 function 签名中的B
类型。 查看predict
的签名,您可能希望在update
function 中使用B
类型作为covariances
。
fn update(
&self,
states: &ArrayBase<A, Ix2>,
covariances: &ArrayBase<B, Ix3>, // use B instead of A
measurements: &ArrayBase<A, Ix2>,
) -> Self::Update {
...
}
编辑:还有一件事,如果我放弃将类型组合作为输入的能力,并且如果我在上面的特征中删除类型参数 B,它就会起作用。 不知何故,第二个类型参数的引入会导致问题。
想象一下,您有两个具有相同T
和A
以及不同B
的 trait 实现。 编译器如何知道使用哪一个?
最后,go 如何解决这个问题? 有没有办法说类型参数是完全独立的,或者至少说关联类型只依赖于第一个类型参数?
将您的特质分为 2 似乎是合理的:
pub trait FilterUpdate<T: Scalar + Lapack, A: Data<Elem=T>> {
type Update;
fn update(&self, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<A, Ix3>, measurements: &ArrayBase<A, Ix2>) -> Self::Update;
}
pub trait Filter<T: Scalar + Lapack, A: Data<Elem=T>, B: Data<Elem=T>> : FilterUpdate<T, A> {
type Prediction;
fn predict(&self, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<B, Ix3>) -> Self::Prediction;
}
那么对于特定A
,您只能有一个update
实现。 或者可能首先使B
成为关联类型,而不是特征的类型参数。
或者您可以保留当前的 API 并明确指定特征类型参数。 根据错误消息,我猜它看起来像这样:
let a = <KalmanFilter<f64> as Filter<f64, OwnedRepr<f64>, ???>>::update(&kf, &states, &covariances, &measurements)
你需要在哪里决定什么???
是。
我猜你最终需要为大多数update
调用这样做。
助手 function 可以简化调用,特别是如果我正确理解B
是什么通常无关紧要并且您可以将其等同于A
:
fn update<T: Scalar + Lapack, A: Data<Elem=T>, F: Filter<T, A, A>>(filter: &F, states: &ArrayBase<A, Ix2>, covariances: &ArrayBase<A, Ix3>, measurements: &ArrayBase<A, Ix2>) -> F::Update { filter.update(states, covariances, measurements) }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.