#macro #level #newtype #logic #experimental

new_type

基于类型逻辑的newtype实验性实现

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次下载

MIT许可证

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));

无运行时依赖