1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2017 年 2 月 22 日

#866科学

MIT 许可证

22KB
328

MIT licensed

simple_units

Rust 的简单单位系统。

它允许您编写既类型安全又“单位安全”的数值代码。

它在稳定 Rust 上运行,但遗憾的是这意味着它不具有可扩展性。所有单位(以及它们的组合)都必须手动编写。宏可以帮助(也许更多的宏魔法可以帮助更多),但仍然是一项大量工作。

对我来说,它已经得到了回报:我在我们正在使用的一个旧 Fortran 程序中找到了一个小的错误 ;-)

所以,如果您喜欢的单位缺失,请告诉我。

对于 Rust,已经有一个更好的单位系统:[Dimensioned](https://github.com/paholg/dimensioned/tree/rmdim),至少需要 Rust 1.15。

还有一个:[runits](https://github.com/jesse99/runits) 和 [uom](https://github.com/iliekturtles/uom)

还有一个 crate 可以帮助您在不同单位之间进行转换:[rink-rs](https://github.com/tiffany352/rink-rs/)

备注

有一些关于 Rust 中单位系统的博客文章/备注

https://www.reddit.com/r/rust/comments/37qut9/typesafe_userdefined_units_of_measure_for_rust/

https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/

https://github.com/jaheba/stuff/blob/master/communicating_intent.md

https://www.reddit.com/r/rust/comments/5uacxs/types_units_and_quantities/

示例

extern crate simple_units;
use simple_units::si_units::*;

fn main() {
    let length = Meter(20.72);
    let time = Second(12.39);

    // Resulting type: MeterPerSecond
    let velocity = length / time;

    // This will not compile:
    // let error = length + time;

    // Multiply by Second gives you Meter:
    let duration = Second(35.0);
    let distance: Meter = velocity * duration;
    // Type (= unit) not needed, will be inferred:
    let distance2 = velocity * duration;
}

支持转换

extern crate simple_units;
use simple_units::si_units::*;
use simple_units::conversion::*;

fn main() {
    let length_in_m = Meter(20.72);
    // Explicit conversion, unit implements ``from``
    let length_in_foot = Foot::from(length_in_m);

    // Compile error:
    // let length_sum = length_in_m + length_in_foot;

    // But this works:
    let length_sum = length_in_m + length_in_foot.into();

    let temperature_in_degc = DegC(20.7);
    // You must provide the type (= unit) here
    let temperature_in_k: Kelvin = temperature_in_degc.into();
}

如果 Rust 允许实现 as 操作符,那就太好了。然后您可以写些这样的东西

extern crate simple_units;
use simple_units::si_units::*;
use simple_units::conversion::*;

fn main() {
    let length_in_m = Meter(20.72);
    let length_in_foot = Foot(12.56);

    // Does not work (yet ?)
    // let length_sum = length_in_m + (length_in_foot as Meter);
}

我有一个更好的单位系统的计划,基于 build.rs 和注释:基本上这意味着要扫描所有的 *.rs Rust 源文件,并评估具有特殊注释的表达式

fn main() {
    let length = 20.72; // #[m]
    let time = 12.39; // #[s]

    // Resulting type: #[m / s]
    // No need to specify, will be inferred
    let velocity = length / time;

    // build.rs will give an error:
    // let error = length + time;

    // Multiply by #[s] gives you #[m]:
    let duration = 35.0; // #[s]
    let distance = velocity * duration; // This would be #[m], but could be omitted
}

注意特殊 #[] 语法来描述单位。在注释开始标记和单位描述之间只允许空格和制表符。之后可以放置任何注释。否则,单位描述将被忽略,如上例所示。

这将在稳定 Rust 上工作。

没有运行时依赖