Rust代码示例——17.2.不要重复编码(Don‘t Repeat Yourself)

宏通过提取出函数或测试单元的通用元素来达到不写重复代码的作用。下面是一个示例,它展示了+=,-+,*=的测试代码的实现。

use std::ops::{Add, Mul, Sub};


macro_rules! assert_equal_len {

    // The `tt` (token tree) designator is used for

    // operators and tokens.

    ($a:expr, $b:expr, $func:ident, $op:tt) => {

        assert!($a.len() == $b.len(),

                "{:?}: dimension mismatch: {:?} {:?} {:?}",

                stringify!($func),

                ($a.len(),),

                stringify!($op),

                ($b.len(),));

    };

}


macro_rules! op {

    ($func:ident, $bound:ident, $op:tt, $method:ident) => {

        fn $func<T: $bound<T, Output=T> + Copy>(xs: &mut Vec<T>, ys: &Vec<T>) {

            assert_equal_len!(xs, ys, $func, $op);


            for (x, y) in xs.iter_mut().zip(ys.iter()) {

                *x = $bound::$method(*x, *y);

                // *x = x.$method(*y);

            }

        }

    };

}


// Implement `add_assign`, `mul_assign`, and `sub_assign` functions.

op!(add_assign, Add, +=, add);

op!(mul_assign, Mul, *=, mul);

op!(sub_assign, Sub, -=, sub);


mod test {

    use std::iter;

    macro_rules! test {

        ($func:ident, $x:expr, $y:expr, $z:expr) => {

            #[test]

            fn $func() {

                for size in 0usize..10 {

                    let mut x: Vec<_> = iter::repeat($x).take(size).collect();

                    let y: Vec<_> = iter::repeat($y).take(size).collect();

                    let z: Vec<_> = iter::repeat($z).take(size).collect();


                    super::$func(&mut x, &y);


                    assert_eq!(x, z);

                }

            }

        };

    }


    // Test `add_assign`, `mul_assign`, and `sub_assign`.

    test!(add_assign, 1u32, 2u32, 3u32);

    test!(mul_assign, 2u32, 3u32, 6u32);

    test!(sub_assign, 3u32, 2u32, 1u32);

}

程序运行结果:
 

$ rustc --test dry.rs && ./dry

running 3 tests

test test::mul_assign ... ok

test test::add_assign ... ok

test test::sub_assign ... ok


test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值