1 个不稳定版本
使用旧的 Rust 2015
0.1.0 | 2017 年 2 月 22 日 |
---|
#866 在 科学
22KB
328 行
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 上工作。