简体   繁体   English

推广添加无符号和有符号整数类型

[英]Generalizing over adding unsigned and signed integer types

I want to have a Rust function that allows adding an u32 ( u64 , u128 ) type to an i32 ( i64 , i128 ) type while checking for overflow. 我想有一个允许添加的防锈功能的u32u64u128 )输入到i32i64i128 ),同时检查溢流型。

My implementation: 我的实施:

/// 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)?)
}

I have another similar one that does the same for u128 and i128 . 我有另一个类似的u128i128 I feel like I am repeating myself. 我觉得我在重复自己。 My tests for those functions also look very similar. 我对这些功能的测试看起来非常相似。

Is there a way I could refactor my code and have just one function instead? 有没有办法可以重构我的代码并只改为一个函数? I am not sure how to generalize over the relationship between u32 and i32 (or u64 and i64 , u128 and i128 ). 我不知道如何通过之间的关系概括u32i32 (或u64i64u128i128 )。

You can use a macro: 你可以使用宏:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM