Rust如何为整数和浮点数实现通用saturating_add饱和加法函数?
要实现基于trait是否存在的静态分发通用饱和加法,可以通过以下两种方案实现,均无需手动枚举所有支持类型,编译期完成分发可直接内联:
Nightly 特化方案
依赖Rust nightly通道的特化特性,实现最简洁直观:
- 首先在
Cargo.toml中引入依赖:
[dependencies] num_traits = "0.2"
- 代码实现:
#![feature(specialization)] use num_traits::Num; use num_traits::ops::saturating::SaturatingAdd; use std::ops::Add; trait SatAddHelper { fn sat_add(self, rhs: Self) -> Self; } // 默认实现:适配无饱和加法的类型(如浮点数),使用普通加法 impl<T: Num + Add<Output = T>> SatAddHelper for T { default fn sat_add(self, rhs: Self) -> Self { self + rhs } } // 特化实现:适配实现了SaturatingAdd的整数类型,使用饱和加法 impl<T: Num + SaturatingAdd> SatAddHelper for T { fn sat_add(self, rhs: Self) -> Self { self.saturating_add(&rhs) } } #[inline(always)] pub fn sat_add<T: SatAddHelper>(x: T, o: T) -> T { x.sat_add(o) }
Stable 兼容方案
如果需要使用稳定版Rust,可以利用autoref的方法解析优先级技巧实现相同效果,无需启用unstable特性:
use num_traits::Num; use num_traits::ops::saturating::SaturatingAdd; use std::ops::Add; // 低优先级 fallback 实现 struct AddFallback; impl AddFallback { #[inline(always)] fn sat_add<T: Num + Add<Output = T>>(&self, x: T, o: T) -> T { x + o } } // 高优先级饱和加法实现 trait SaturatingAddImpl { #[inline(always)] fn sat_add<T: Num + SaturatingAdd>(&self, x: T, o: T) -> T { x.saturating_add(&o) } } impl<T: SaturatingAdd> SaturatingAddImpl for &T {} impl SaturatingAddImpl for AddFallback {} #[inline(always)] pub fn sat_add<T: Num>(x: T, o: T) -> T { // 方法解析时优先匹配&T的SaturatingAddImpl实现,无匹配则降级到AddFallback (&x).sat_add(x, o) }
测试验证
fn main() { // 整数饱和逻辑验证 assert_eq!(sat_add(u32::MAX, 1), u32::MAX); assert_eq!(sat_add(i32::MIN, -10), i32::MIN); assert_eq!(sat_add(123u8, 10), 133); // 浮点数逻辑验证 assert_eq!(sat_add(f32::INFINITY, 100.0), f32::INFINITY); assert_eq!(sat_add(2.5f64, 3.7), 6.2); }
内容的提问来源于stack exchange,提问作者SO is dead
相关产品推荐
相关产品推荐

