Outline

本篇主要介紹何為 Yoda Conditions,以及在哪些語言哪些時候被使用是恰當和不恰當的。

Yoda Conditions

所謂 Yoda Conditions 指的是像這種寫法:

1
2
3
if (5 == n) {
  // do something...
}


我剛學程式時條件式都是這樣寫的:

1
2
if (n == 5) {
}

Yoda Conditions 相較於第二種寫法,其優點在於能夠避免不小心打錯字所發生的錯誤。 例如在 C 語言,這就是初學者常見的錯誤,當你不小心打成

1
if (n = 5) // ...

n 就會被賦值為5,而這個條件則會永久為true,完全不同於原意。 而用 Yoda 的方式寫,打錯的話則會變成:

1
if (5 = n) // ...

因為 5 是一個常值,無法用 “ = ” 賦值,編譯器在這裡就會報錯,而避免了因打錯字而產生BUG卻找不出來的問題。

這種寫法實在稱不上是什麼高明的技巧,而是為了避免掉程式語言設計缺失造成BUG而折衷的產物。 雖然這種寫法可以減少BUG產生的情形,但同時也損失了程式的易讀性。 就像在自然語言中,你會問『你現在是18歲嗎?』而很少說『18歲是你現在的年紀嗎?』,5 == n 這種反過來的寫法也不太直覺.不太自然。

Yoda Conditions 最酷炫的地方大概就是他的名字了。是的,就是星際大戰中的尤達大師XD

尤達的問題根源

我認為一個設計堪用的語言,應該直接在語言的機制上避免這種問題,而非讓 Programmer 去使用這種尷尬的尤達寫法。

這個「打錯字」問題的病原在於以下幾點:

  1. 語言允許在 if(...); while(...) 的括號中賦值
  2. 語言的賦值方法會回傳值
  3. 回傳的值能夠被隱式轉換為布林值(true / false)

程式語言只要能夠避掉以上任一點,就不會發生將”等於判斷”誤打為”賦值”的情況。

各個程式語言中的尤達

僅列出我較熟悉或是很熱門的語言中以「 = 」 賦值,並以「 == 」判斷相等的語言。 那種 (let a 5) 完全與此問題無關的語言就不在列表中啦XD

編譯/直譯錯誤

  • Java error: incompatible types: int cannot be converted to boolean
  • C# (VS2010) Error : Cannot implicitly convert type 'int' to 'bool'
  • Python (2.7.8): SyntaxError: invalid syntax
  • Swift: Type '()' does not conform to protocol 'BooleanType'

編譯/直譯警告

  • Ruby (2.0.0): warning: found = in conditional, should be ==

  • C and C++ (clang-600.0.56 -Wall): warning: using the result of an assignment as a condition without parentheses [-Wparentheses]

擺爛

  • PHP (5.5.14)
  • Perl (5.18.2)
  • JavaScript (node 0.10.23)

結論

  1. 如果你在寫 PHP / Perl / JavaScript,不得已而繼續使用尤達大師是可理解的
  2. 寫 C/C++ 的時候,將編譯器警告選項開啟,應該可以避免使用尤達大師
  3. 如果你在寫 C#, Java…,不該把在其他語言的習慣帶過來,因為在這裡沒有這種問題。當然更該注意不要寫出if (b == true) 這種奇怪的程式碼。

另外碎碎念一下,像 Swift 的賦值回傳 (),亦即「賦值不應有回傳值」的想法我是挺認同的。不過多數的語言都沒有採用,為了讓大家可以方便地使用這種寫法(笑):

1
a = b = c

Creative Commons License
This work by SudoPotato is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

見人言某語言優雅有感

有些語言可能可以說是好用.靈巧.在programmer能力值高的情況下能產出好的程式但卻很難被歸類為 “優雅”##比如說這麼一個語言混淆應屬於物件的 method 或獨立的 function甚至狂熱試圖把一切都當成物件然後鼓勵一堆人寫出 `3.times do` 這種念起來很順 …… Continue reading

[Note]Setup SSH on Fedora in VirtualBox

Published on January 30, 2015