如何将c#抽象类映射到Rust

本文关键字:映射 Rust 抽象类 | 更新日期: 2023-09-27 18:26:15

这可能是一个措辞拙劣的问题,但这里有一个例子:

给定这些结构;

pub struct Poll {
    _lat: f64,
    _lon: f64,
    _at: i64,
    _heading: f64,
    _speed: f64,
}
pub struct Waypoint {
    _lat: f64,
    _lon: f64,
}

以及这种特性;

pub trait CoordMeasure {
    fn dist_to(&self, other: &Self ) -> f64;
}

如何避免像以前那样重复此代码?

impl CoordMeasure for Poll {
    fn dist_to(&self, other: &Poll) -> f64 {
        super::core::distance(self, other)
    }
}
impl CoordMeasure for Waypoint {
    fn dist_to(&self, other: &Waypoint) -> f64 {
        super::core::distance(self, other)
    }
}

我有两个对相同函数距离的调用。

pub fn distance<T: Coord>(a: &T, b: &T ) -> f64 {
        let lat1_rads = (90.0 - a.lat()).to_radians();
        let lat2_rads = (90.0 - b.lat()).to_radians();
        let lon_rads = (b.lon() - a.lon()).to_radians();
        let cos_of_lat1 = lat1_rads.cos();
        let cos_of_lat2 = lat2_rads.cos();
        let sin_of_lat1 = lat1_rads.sin();
        let sin_of_lat2 = lat2_rads.sin();
        let cos_of_lons = lon_rads.cos();
        let equation = ((cos_of_lat2 * cos_of_lat1) + (sin_of_lat2 * sin_of_lat1 *    cos_of_lons)).acos();
        6334009.6 * equation
}

这只是重复的一行代码,但在更好的示例中可能会有更多。在C#中,这段代码将在Waypoint和Poll派生的抽象类中编写一次。Rust处理这种情况的惯用方式是什么?

如何将c#抽象类映射到Rust

通用实现是可能的:

impl<T: Coord> CoordMeasure for T {
    fn dist_to(&self, other: &T) -> f64 {
        super::core::distance(self, other)
    }
}

但在这种特殊情况下,您应该完全删除CoordMeasure,并在Coord上实现它作为默认方法:

trait Coord {
    …
    fn dist_to(&self, other: &Self) -> f64 {
        super::core::distance(self, other)  // or move its contents in here
    }
}

您可能还想使其能够处理其他类型的other(我看不出other必须与self:类型相同的任何直接原因

fn dist_to<Other: Coord>(&self, other: &Other) -> f64 {
    let lat1_rads = (90.0 - self.lat()).to_radians();
    let lat2_rads = (90.0 - other.lat()).to_radians();
    let lon_rads = (b.lon() - self.lon()).to_radians();
    let cos_of_lat1 = lat1_rads.cos();
    let cos_of_lat2 = lat2_rads.cos();
    let sin_of_lat1 = lat1_rads.sin();
    let sin_of_lat2 = lat2_rads.sin();
    let cos_of_lons = lon_rads.cos();
    let equation = ((cos_of_lat2 * cos_of_lat1) + (sin_of_lat2 * sin_of_lat1 *    cos_of_lons)).acos();
    6334009.6 * equation
}