When you look at the dark side, careful you must be.
For the dark side looks back.

在编程中我们常常不得不面对 typo 所带来的隐形程序漏洞,尤其是在条件判断表达式中。例如将等于 (==) 或不等于 (!=) 错打成赋值 (=),使得判断结果始终为真 (True),导致程序出现非期待的行为。使用 yoda conditions 能够避免上述错误的出现。

Yoda conditions 是一种编程风格,将条件判断表达式中的操作符两边的部分位置互换,与常见的编写顺序相反,其中变量位于操作符右边,常量、字面值或函数位于操作符左边。通过调换这两部分的位置,编译器就能够在出现上述的 typo 错误时检查出来,从而避免了程序漏洞的产生。Yoda conditions 得名于电影星战中的尤达大师 (Master Yoda)。Yoda 说话时使用一种宾主动 (object-subject-verb) 倒装的语言模式[1],与颠倒条件判断式的编程风格如出一辙 (笔者觉得中文翻译为“山东话条件式 ”则颇为贴切😝)。

下面这个例子说明了 yoda conditions 与正常条件表达式的不同:

1
2
3
4
5
// normal conditions
if (myAnswer == 42) { /* do something */ }

// yoda conditions
if (42 == myAnswer) { /* do something */ }

那么我们什么时候应该使用 yoda contions 呢?读者可以参考 Yoda Conditions: To Yoda or Not to Yoda 这篇文章[2]。总得来说,分为以下几种情况:

  1. 在判等的条件中使用,在比较大小 (typo 不会导致赋值) 的条件中不必使用
  2. 在变量与常量、字面值和函数的判等条件中使用
  3. 在比较变量与变量的条件中不必使用
  4. 在比较函数与常量、字面值的条件中不必使用

虽然 yoda conditions 能够有效避免 typo 错误的产生,但是有不少针对于 yoda conditions 的批评声[3,4],认为其损害了程序的可读性,给阅读者带来了心智负担。不使用 yoda conditions,而是仔细编写能够覆盖每条代码路径的单元测试样例也能够使得 typo 错误被发现。读者可能发现了上述条件 3 中无法使用 yoda conditions 发现错误,也需要依赖于单元测试。因此笔者也认为程序的可读性要优先于这些 tricky 的技巧,毕竟软件工程中的代码维护者不只有编写者一个人。

软件工程中没有银弹,但是单元测试也许能算。

参考文献

1. Geoffrey K. Pullum. 2005. “YODA’S SYNTAX THE TRIBUNE ANALYZES”. http://itre.cis.upenn.edu/~myl/languagelog/archives/002173.html
2. Tonya Mork. 2016. “Yoda Conditions: To Yoda or Not to Yoda”. https://knowthecode.io/yoda-conditions-yoda-not-yoda
3. Mike Classic. 2017. “Yoda Conditions: Why You Shouldn’t Use Them”. https://mikeclassic.ca/blog/yoda-conditions-why-you-shouldnt-use-them
4. Grégoire Paris. 2020. “Why using Yoda conditions you should probably not be”. https://dev.to/greg0ire/why-using-yoda-conditions-you-should-probably-not

License

Creative Commons License Logo
This article is licensed under CC BY-NC-SA 4.0.
Please contact me for commercial use.