泛化添加无符号和有符号整数类型



我想要一个 Rust 函数,允许在检查溢出的同时将u32(u64u128(类型添加到i32(i64i128(类型。

我的实现:

/// Add u32 to i32. In case of an overflow, return None.
fn checked_add_i32_u32(a: i32, b: u32) -> Option<i32> {
let b_half = (b / 2) as i32;
let b_rem = (b % 2) as i32;
Some(a.checked_add(b_half)?.checked_add(b_half)?
.checked_add(b_rem)?)
}
/// Add u64 to i64. In case of an overflow, return None.
fn checked_add_i64_u64(a: i64, b: u64) -> Option<i64> {
let b_half = (b / 2) as i64;
let b_rem = (b % 2) as i64;
Some(a.checked_add(b_half)?.checked_add(b_half)?
.checked_add(b_rem)?)
}

我还有另一个类似的,对u128i128做同样的事情.我觉得我在重复自己。我对这些功能的测试看起来也非常相似。

有没有办法重构我的代码并只有一个函数?我不确定如何概括u32i32(或u64i64u128i128(之间的关系。

您可以使用宏:

trait CustomAdd: Copy {
type Unsigned;
fn my_checked_add(self, b: Self::Unsigned) -> Option<Self>;
}
macro_rules! impl_custom_add {
( $i:ty, $u:ty ) => {
impl CustomAdd for $i {
type Unsigned = $u;
fn my_checked_add(self, b: $u) -> Option<$i> {
let b_half = (b / 2) as $i;
let b_rem = (b % 2) as $i;
Some(self.checked_add(b_half)?.checked_add(b_half)?
.checked_add(b_rem)?)
}
}
}
}
impl_custom_add!(i32, u32);
impl_custom_add!(i64, u64);
// etc.
#[test]
fn tests() {
assert_eq!(123.my_checked_add(10_u32), Some(133));
}

相关内容

  • 没有找到相关文章

最新更新