我为度量空间中的向量创建了抽象数据类型,但是编译器抱怨,因为它不认识到作为参数的实现就是这种类型。
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`
为什么不认识到RNPoint
是MetricPoint
?
答案 0 :(得分:2)
您可以编译并通过测试的地方并不远。只需更改:
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
,您可以指定当前结构的类型。它更具通用性和可读性。
答案 1 :(得分:0)
谢谢。正如某些人所说,但雨果更明确的是解决方案是自我。这是最终代码:
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)
}
}
关于抽象类,我写了抽象数据类型,但是堆栈溢出改变了它,我没有注意到。抱歉