繁体   English   中英

如何指定特征函数采用实现该特征的参数?

[英]How can I specify that a trait function takes an argument implementing the trait?

我为度量空间中的向量创建了抽象数据类型,但是编译器抱怨,因为它不认识到作为参数的实现就是这种类型。

trait MetricPoint {
    fn square_distance(&self, other: &MetricPoint) -> f64;
}

struct RNPoint {
    coordinates: Vec<f64>,
}

impl RNPoint {
    fn new(coordinates: &[f64]) -> RNPoint {
        RNPoint {
            coordinates: coordinates.to_vec(),
        }
    }
}

impl MetricPoint for RNPoint {
    fn square_distance(self: &RNPoint, other: &RNPoint) -> f64 {
        let min_len = self.coordinates.len().min(other.coordinates.len());
        let mut sum = 0.0;
        for i in 0..min_len {
            let diff = self.coordinates[i] - other.coordinates[i];
            sum += diff * diff;
        }
        sum
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn square_distance() {
        let p1 = RNPoint::new(&[0.0, 0.0]);
        let p2 = RNPoint::new(&[1.0, 0.0]);
        let d = p1.square_distance(&p2);
        assert_eq!(d, 1.0)
    }
}

编译器:

error[E0053]: method `square_distance` has an incompatible type for trait
  --> points/src/lib.rs:19:44
   |
2  |     fn square_distance(&self, other: &MetricPoint) -> f64;
   |                                      ------------ type in trait
...
19 |     fn square_distance(self:&RNPoint,other:&RNPoint)->f64 {
   |                                            ^^^^^^^^ expected trait MetricPoint, found struct `RNPoint`
   |
   = note: expected type `fn(&RNPoint, &dyn MetricPoint) -> f64`
              found type `fn(&RNPoint, &RNPoint) -> f64`

为什么不认识到RNPointMetricPoint

您距离编译并通过测试的地方并不远。 只是改变:

fn square_distance(&self, other: &MetricPoint) -> f64;

fn square_distance(&self, other: &Self) -> f64;

然后选择

fn square_distance(self: &RNPoint, other: &RNPoint) -> f64

fn square_distance(self: &RNPoint, other: &Self) -> f64

通过编写Self ,您可以指定当前结构的类型。 它更具通用性和可读性。

谢谢。 正如某些人所说,但雨果更明确的是解决方案是自我。 这是最终代码:

trait Metric {
    fn distance(&self, other: &Self) -> f64;
}

struct RNPoint {
    coordinates: Vec<f64>,
}

impl RNPoint {
    fn new(coordinates: &[f64]) -> RNPoint {
        RNPoint {
            coordinates: coordinates.to_vec(),
        }
    }
}

impl Metric for RNPoint {

    fn distance(&self, other: &Self) -> f64 {
        let sum:f64=self.coordinates.iter()
            .zip(other.coordinates.iter())
            .map(|(&c1, &c2)| {
                let diff = c1 - c2;
                diff * diff
            })
            .sum();
         sum.sqrt()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_distance() {
        let p1 = RNPoint::new(&[0.0, 0.0]);
        let p2 = RNPoint::new(&[1.0, 0.0]);
        let d = p1.distance(&p2);
        assert_eq!(d, 1.0)
    }
}

关于抽象类,我写了抽象数据类型,但是堆栈溢出改变了它,我没有注意到。 为......感到抱歉

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM