为什么 Rust 的 assert_eq!使用匹配实现? [英] Why is Rust's assert_eq! implemented using a match?

查看:395
本文介绍了为什么 Rust 的 assert_eq!使用匹配实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 Rust 的 assert_eq! 宏实现.为简洁起见,我只复制了第一个分支:

Here's Rust's assert_eq! macro implementation. I've copied only the first branch for brevity:

macro_rules! assert_eq {
    ($left:expr, $right:expr) => ({
        match (&$left, &$right) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    panic!(r#"assertion failed: `(left == right)`
  left: `{:?}`,
 right: `{:?}`"#, left_val, right_val)
                }
            }
        }
    });
}

这里 match 的目的是什么?为什么检查不等式还不够?

What's the purpose of the match here? Why isn't checking for non-equality enough?

推荐答案

好的,让我们移除匹配项.

Alright, let's remove the match.

    macro_rules! assert_eq_2 {
        ($left:expr, $right:expr) => ({
            if !($left == $right) {
                panic!(r#"assertion failed: `(left == right)`
  left: `{:?}`,
 right: `{:?}`"#, $left, $right)
            }
        });
    }

现在,让我们选择一个完全随机的例子...

Now, let's pick a completely random example...

fn really_complex_fn() -> i32 {
    // Hit the disk, send some network requests,
    // and mine some bitcoin, then...
    return 1;
}

assert_eq_2!(really_complex_fn(), 1);

这将扩展为...

{
    if !(really_complex_fn() == 1) {
        panic!(r#"assertion failed: `(left == right)`
  left: `{:?}`,
 right: `{:?}`"#, really_complex_fn(), 1)
    }
}

如您所见,我们调用了函数两次.这不太理想,如果每次调用函数的结果都可能发生变化,则更是如此.

As you can see, we're calling the function twice. That's less than ideal, even more so if the result of the function could change each time it's called.

match 只是一种快速、简单的方法,可以对宏的两个参数"进行精确计算一次并将它们绑定到变量名称.

The match is just a quick, easy way to evaluate both "arguments" to the macro exactly once and bind them to variable names.

这篇关于为什么 Rust 的 assert_eq!使用匹配实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆