用 常量泛型(const_generics) 实现计量单位检查与转换
重新实现 测试实例:单位说明
https://doc.rust-lang.org/stable/rust-by-example/generics/phantom/testcase_units.html
rust 1.47 说是引入 const_generics 但好像只有系统库能用
还是要上 nightly 使用 rustc 1.49.0-nightly (8dae8cdcc 2020-10-12)
#![feature(const_generics)]
use core::ops::Add;
use core::marker::PhantomData;
trait LengthType<const F: f64> {}
#[derive(Debug, Clone, Copy)]
struct Length<const F: f64>(f64, PhantomData<dyn LengthType<F>>);
type Meter = Length<1.0>;
type Mm = Length<1000.0>;
type Inch = Length<{1000.0/25.4}>;
impl<const F1: f64> Length<F1> {
fn new(val: f64) -> Self {
Length(val, PhantomData)
}
fn value(self) -> f64 {
self.0
}
fn factor() -> f64 {
F1
}
fn _from<const F2: f64>(src: Length<F2>) -> Self {
Self::new(src.0 * F1 / F2)
}
fn _into<const F2: f64>(self) -> Length<F2> {
Length::new(self.0 * F2 / F1)
}
}
impl<const F: f64> Add for Length<F> {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
Self::new(self.0 + other.0)
}
}
fn main() {
let m1 = Meter::new(1.0);
let inch3 = Inch::new(3.0);
let mm40 = Mm::new(40.0);
let a = m1 + inch3._into();
println!("m1 + inch3 = {} m", a.value());
let b = mm40 + inch3._into();
println!("mm40 + inch3 = {} mm", b.value());
let c = mm40 + m1._into();
println!("mm40 + m1 = {} mm", c.value());
}
输出为:
m1 + inch3 = 1.0762 m
mm40 + inch3 = 116.2 mm
mm40 + m1 = 1040 mm
还有几个遗留问题待解决:
// 1. 约束条件能做吗
trait LengthType<const F: f64> where F > 0.0 {}
// 2. 类型转换 From 怎么实现
impl<const F1: f64, const F2: f64> From<Length<F2>> for Length<F1> {}
// 3. 加法和减法 下面两种方法都能实现 那种比较好?
impl<const F: f64> Add for Length<F> {} // let a = m1 + inch3._into();
impl<const F1: f64, const F2: f64> Add<Length<F2>> for Length<F1> {} // let b = m1 + inch3;
1
共 1 条评论, 1 页
评论区
写评论赞!同想学习类型编程。