Я пытаюсь создать хороший интерфейс для физических измерений, таких как углы, масса, скорости и т. Д. Я хочу, чтобы они предлагали проверку размерного анализа во время компиляции, в идеале с нулевыми накладными расходами во время выполнения. Я думаю, что Rust мог бы быть очень подходящим для этого, особенно с чертами.
То, что у меня до сих пор выглядит примерно так:
pub trait Measure {
type Underlying: Clone; // the underlying storage type (most often a Float)
fn name() -> &'static str;
fn default_unit() -> &'static str;
fn in_default_unit(&self) -> Self::Underlying;
fn from_default_unit(m: Self::Underlying) -> Self;
}
и реализация будет выглядеть примерно так:
#[derive(Debug, Clone, PartialEq)]
pub struct Angle<'a> {
radians: Float, // dynamic but either a `f64` or `f32`
}
impl<'a> Angle<'a> {
fn from_radians(radians: Float) -> Self {
Self { radians }
}
}
impl<'a> Measure<'a> for Angle<'a> {
type Underlying = Float;
fn name() -> &'static str {
"angle"
}
fn default_unit() -> &'static str {
"radian"
}
fn in_default_unit(&self) -> Self::Underlying {
self.radians
}
fn from_default_unit(m: Self::Underlying) -> Self {
Self::from_radians(m)
}
}
Я хочу добавить общие операции, такие как перегрузка оператора +
и аналогичные, но я хочу сделать это таким образом, чтобы он был связан с чертой Measure
, поэтому мне не нужно создавать его для каждого Measure
.
Я пытался создать промежуточный класс для операций, которые Angle
могли бы Deref
, но столкнулись с некоторыми проблемами со временем жизни, и я думаю, что этот маршрут на самом деле может быть невозможен.
Мне кажется, что это достаточно распространенная потребность, что есть решение. Как я могу это сделать?