三元運算符普遍存在於其餘語言中,好比:javascript
python:java
val = trueValue if expr else falseValue
javascript:python
const val = expr ? trueValue : falseValue
c、c++:c++
const char *val = expr ? "trueValue" : "falseValue";
然而,被普遍支持的三目運算符在golang中倒是不存在的!若是咱們寫出相似下面的代碼:golang
val := expr ? "trueValue" : "falseValue"
那麼編譯器就該抱怨了:invalid character U+003F '?'
。意思是golang中不存在?
這個運算符,編譯器不認識並且非字母數字下劃線也不能用作變量名,天然也就看成是非法字符了。express
然而這是爲何呢,其實官方給出了解釋,這裏簡單引用一下:函數
The reason ?: is absent from Go is that the language's designers had seen the operation used too often to create impenetrably complex expressions. The if-else form, although longer, is unquestionably clearer. A language needs only one conditional control flow construct.post
golang中不存在?:運算符的緣由是由於語言設計者已經預見到三元運算符常常被用來構建一些極其複雜的表達式。雖然使用if進行替代會讓代碼顯得更長,但這毫無疑問可讀性更強。一個語言只須要有一種條件判斷結構就足夠了。性能
毫無疑問,這是在golang「大道至簡」的指導思想下的產物。設計
這段話其實沒問題,由於某些三元運算符的使用場景確實會下降代碼的可讀性:
const status = (type===1?(agagin===1?'再售':'已售'):'未售') const word = (res.distance === 0) ? 'a' : (res.distance === 1 && res.difference > 3) ? 'b' : (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) ? 'c' : 'd';
乍一看確實很複雜,至少第二個表達式不花個20秒細看可能無法理清控制流程(想象一下當縮進錯位或是徹底沒有縮進的時候)。
若是把它們直接轉化成if語句是這樣的:
let status = '' if (type === 1) { if (again === 1) { status = '再售' } else { status = '已售' } } else { status = '未售' } let word = '' if (res.distance === 0) { word = 'a' } else { if (res.distance === 1 && res.difference > 3) { word = 'b' } else { if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) { word = 'c' } else { word = 'd' } } }
看起來並無多少的改善,特別是例2,三層嵌套,不論是誰review到這段代碼不免不會抱怨你幾句。
然而事實上這些代碼是能夠簡化的,考慮到三元運算符老是會給變量一個值,所以最後的else
其實能夠看做是變量的默認值,因而代碼能夠這麼寫:
let status = '未售' if (type === 1) { if (again === 1) { status = '再售' } else { status = '已售' } } let word = 'd' if (res.distance === 0) { word = 'a' } else { if (res.distance === 1 && res.difference > 3) { word = 'b' } else { if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) { word = 'c' } } }
其次,對於例2,顯然可使用else if
來清除嵌套結構:
let word = 'd' if (res.distance === 0) { word = 'a' } else if (res.distance === 1 && res.difference > 3) { word = 'b' } else if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) { word = 'c' }
如今再來看,顯然使用if
語句的版本的可讀性更高,邏輯也更清晰(經過去除嵌套)。
然而事實也不盡然。除了用三元運算符表達流程控制以外,事實上更常見更普遍的一個應用是以下這樣的表達式:
const val = expr ? trueValue : falseValue const func = (age) => age > 18 ? '成年人' : '未成年人'
相似上述經過一個簡短的條件表達式來肯定變量的值,在開發中的出現頻率是至關高的。這時三元運算符的意圖更清晰,可讀性也較if語句更高,特別是配合匿名函數(lambda表達式)使用能夠極大簡化咱們的代碼。
對此python的解決之道是之支持上述的簡化版三元表達式,同時表達式不支持嵌套,達到了揚長避短的目的。不過代價是編譯器的相關實現會複雜化。
而對於golang來講一個簡單的能只經過單遍掃描便可完成ast構建的編譯器是其保持急速的構建速度的祕訣之一,爲了這樣簡單的功能增長編譯器實現的複雜度是不可接受的。同時因爲golang「大道至簡」的哲學,能用現有語法結構解決的問題,天然不會再添加新的語法。
不過仍是有辦法的,雖然不推薦:
func If(cond bool, a, b interface{}) { if cond { return a } return b } age := 20 val := If(age > 18, "成年人", "未成年人").(string)
不推薦這麼作是有幾個緣由:
最後總結一下:
三元運算符的優勢:
但三元運算符也有明顯的缺點:
因此這是一個見仁見智的問題,總之只能入鄉隨俗了。
https://juejin.im/post/6844903561759850510
https://www.it-swarm.dev/zh/javascript/替代js中的嵌套三元運算符/1055944752/