5个版本 (3个破坏性更新)
0.4.1 | 2023年1月16日 |
---|---|
0.4.0 | 2021年8月20日 |
0.3.0 | 2020年11月8日 |
0.2.0 | 2020年10月31日 |
0.1.0 | 2020年10月16日 |
#1610 in Rust模式
每月38次下载
18KB
265 行
new_type
轻松构建Rust中的newtype。 :)
使用可能很危险。 :(
请访问文档: https://docs.rs/new_type
lib.rs
:
欢迎,程序员朋友! 👋🏼
newtype宏非常简单
newtype!(Meters, Centimeters);
let distance_one = Meters(10);
let distance_two = Meters(5);
let distance_three = Centimeters(5);
// Successfully add the same type.
assert_eq!(distance_one + distance_two, Meters(15))
// Compilation error: expected struct `Meters`, found struct `Centimeters`
// assert_eq!(distance_one + distance_three, Meters(15))
底层原理 ⚙️
newtype使用泛型类型参数实现。通过这个类型参数,它进行了一种“类型级别的 derive”操作,即通过委派到基础类型的实现来实现操作。这对于任何级别的嵌套newtype都有效,如果这有任何用处的话。有关详细信息,请参阅[newtype]。
危险警告 ⚠️
强烈建议显式地将预期的类型传递给元组构造函数,因为默认情况下任何类型都可以通过泛型类型参数。这绝对是一个陷阱,但由于泛型类型参数是此crate操作的核心,因此无法明显避免。如果您有任何想法,请提交PR。
// We specify a default type.
// The default type is only relevant for calls to T::default() and only if there is no reason for the compiler to infer another type.
newtype!(Meters: f32);
// Footgun right here, we pass an integer, so it will be an i32.
let distance_one = Meters(10);
// Footgun possible here, we pass a float, so it would be a f64 by default.
// Because we add it with an explicit f32 type the compiler can infer it needs to be an f32 as well.
let distance_two = Meters(5.0);
// The recommended way to construct values of the newtype.
let distance_three = Meters(5.0_f32);
assert_eq!(distance_two + distance_three, Meters(10.0));
// Compilation error: expected integer, found floating-point number
// assert_eq!(distance_one + distance_two, Meters(15))
// Footgun here, f64 is infered for the call to T::default() despite f32 being the default type parameter.
assert_eq!(Meters::default(), Meters(0.0_f64));