【发布时间】:2021-04-15 07:36:26
【问题描述】:
我又一次尝试满足 Rust 中的类型检查器的乐趣。这是我对即将出现的代码示例的模糊看法。我有一个特征,它的方法需要一些参数,并且为了具有灵活性,我希望能够以任何可能的组合将参数设为特定类型,只要传入类型的关联类型实现给定的特征.
注意 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;
}
然后我有一个结构体,它实现了这个特征并且也不关心哪些输入被赋予特征方法,只要它们的关联类型实现给定的特征,所以这是结构和实现的样子:
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,它就会起作用。不知何故,第二个类型参数的引入会导致问题。
【问题讨论】:
标签: rust