【typenum】 17 非零标记及改进建议

一、源码

这段代码定义了一个标记 trait NonZero,用于在类型系统中表示"非零"的数值类型。这是 Rust 类型级编程(type-level programming)的典型模式,常见于类型算术(type-level arithmetic)库中。

  1. 定义
/// A **marker trait** to designate that a type is not zero. All number types in this
/// crate implement `NonZero` except `B0`, `U0`, and `Z0`.
pub trait NonZero: Sealed {}
  1. B1实现(bit.rs)
impl NonZero for B1 {}
  1. UInt实现(uint.rs)
impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
  1. PInt、NInt实现(int.rs)
impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
impl<U: Unsigned + NonZero> NonZero for NInt<U> {}

二、核心定义 (marker_traits.rs)


pub trait NonZero: Sealed {}
  • 标记 trait:没有方法或关联类型,仅用于类型分类

  • 作用:标识该类型代表非零值

  • Sealed:这是一个密封 trait,防止外部类型实现

  • 注释说明:除了 B0、U0 和 Z0 外,所有数值类型都实现此 trait

三、各类型实现

  1. 位类型实现 (bit.rs)

impl NonZero for B1 {}
  • B1 表示二进制位 1

  • 只有 B1 实现 NonZero,B0 不实现(符合"非零"定义)

  1. 无符号整数实现 (uint.rs)

impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
  • UInt<U, B> 是类型级无符号整数的通用结构

  • 任何由 Unsigned 类型 U 和位 B 组成的 UInt 都自动是非零

  • 注意:UInt<UTerm, B0>(即 U0)不实现此 trait

  1. 有符号整数实现 (int.rs)

impl<U: Unsigned + NonZero> NonZero for PInt<U> {}  // 正整数
impl<U: Unsigned + NonZero> NonZero for NInt<U> {}  // 负整数
  • PInt 表示正整数,NInt 表示负整数

  • 只有当底层无符号类型 U 是 NonZero 时,它们才是 NonZero

  • 例如:

    • PInt 是 NonZero(因为 U1 是 NonZero)

    • PInt 不是 NonZero(因为 U0 不是 NonZero)

四、设计意义

  1. 类型安全:

fn divide<T: NonZero>(numerator: i32, _denominator: T) -> i32 {
    numerator / unsafe { std::mem::transmute::<T, i32>(_denominator) }
}

保证除数永远不会是零

  1. 编译时验证:

    trait SafeDivision {
        type Output;
    }

    impl<T: NonZero> SafeDivision for T {
        type Output = Self;
    }
  1. 与零类型互补:
  • Zero trait 和 NonZero trait 共同覆盖所有数值类型

  • 通过 trait 约束可以明确区分零/非零场景

五、典型使用场景

  1. 类型级算术运算:

fn generic_fn<T: NonZero>() {
    // 保证T不是零类型
}
  1. 安全数学运算:

    struct Ratio<N, D: NonZero> {
        numerator: N,
        denominator: D,
    }
硬件寄存器操作(确保不写零值到特定寄存器)

这种模式在需要编译时保证数值属性的场景非常有用,特别是嵌入式开发、密码学、区块链等对安全性要求高的领域。

六、改进建议

  1. 正整数类型改名
原类型新命名数学含义扩展性设计
UInt<U,B>UPos<U,B>二进制无符号正整数 (2*U + B)保留U前缀与无符号体系一致
PIntSPos有符号正整数S前缀(Signed)为小数/浮点数预留
  1. 负整数类型改名
原类型新命名数学含义扩展性设计
NIntSNeg有符号负整数明确负号语义,支持后续小数/浮点数实现
  1. 扩展预留设计

/// 有符号类型标记(为小数预留)
pub trait Sign {
    const IS_POSITIVE: bool;
}

impl<U: Unsigned> Sign for SPos<U> {
    const IS_POSITIVE: bool = true;
}

impl<U: Unsigned> Sign for SNeg<U> {
    const IS_POSITIVE: bool = false;
}

/// 未来可扩展的小数类型
pub struct SFrac<U: Unsigned, S: Sign> { /*...*/ }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liuyuan77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值