Go語(yǔ)言為什么不支持三元運(yùn)算符原理解析
引言
這是一個(gè)很多其他語(yǔ)言工程師轉(zhuǎn) Go 語(yǔ)言的時(shí)間節(jié)點(diǎn),這就難免不論一番比較。其中一個(gè)經(jīng)典的運(yùn)算上的就是 “三元運(yùn)算符”:
為什么 Go 語(yǔ)言不支持三元運(yùn)算符,Go 不支持三元運(yùn)算符就是設(shè)計(jì)的不好,是歷史在開倒車嗎?
今天就由煎魚來(lái)和大家一起摸索為什么。
三元運(yùn)算符是什么
三元運(yùn)算符,在典型的數(shù)學(xué)意義上,或者從解析器的角度來(lái)看,是一個(gè)需要三個(gè)參數(shù)的運(yùn)算符。而我們?nèi)粘V?,最常見的是二元運(yùn)算符:
x?+?y x?/?y x?*?y
還有一元運(yùn)算符:
-a ~b !c
以及今天的男主角 “三元運(yùn)算符”。在 C/C++ 等多種語(yǔ)言中,我們可以根據(jù)條件聲明和初始化變量的習(xí)慣來(lái)選擇性使用三元條件運(yùn)算符:
int?index?=?val?>?0???val?:?-val
Go 使用三元運(yùn)算符
想在 Go 語(yǔ)言里也使用三元運(yùn)算符時(shí),發(fā)現(xiàn)居然沒(méi)有...想要實(shí)現(xiàn)與上面相同的代碼段的方式似乎只能:
var?index?int if?val?>?0?{ ????index?=?val }?else?{ ????index?=?-val }
看上去十分的冗余,不夠簡(jiǎn)潔。
為什么 Go 沒(méi)有三元運(yùn)算符
為什么 Go 沒(méi)有 ?:
操作符,沒(méi)有的話,官方推薦的方式是怎么樣的。
通過(guò) Go FAQ 我們可以得知:
Go 官方就是推薦我們使用前面提到的方式來(lái)替代,并且明確了如下態(tài)度:
- Go 中沒(méi)有
?:
的原因是語(yǔ)言的設(shè)計(jì)者看到這個(gè)操作經(jīng)常被用來(lái)創(chuàng)建難以理解的復(fù)雜表達(dá)式。 - 在替代方案上,if-else 形式雖然較長(zhǎng),但無(wú)疑是更清晰的。一門語(yǔ)言只需要一個(gè)條件控制流結(jié)構(gòu)。
整體來(lái)講,Go 語(yǔ)言的設(shè)計(jì)者是為了考慮可讀性拒絕了實(shí)現(xiàn)三元運(yùn)算符,"less is more." 也是標(biāo)榜臺(tái)詞了。
社區(qū)爭(zhēng)議
Go 語(yǔ)言的一些點(diǎn)與眾不同,基本是大家皆知的。無(wú)論是 if err != nil,又或是本次的三元運(yùn)算符,要大家用 if-else 替代:
if?expr?{ ????n?=?trueVal }?else?{ ????n?=?falseVal }
反對(duì)
因此有社區(qū)小伙伴給出了反對(duì),基本分為如下幾類:
- 認(rèn)為 if-else 也有以類似情況能被濫用,設(shè)計(jì)者的理由不夠充分,認(rèn)為是 “借口”。
- 認(rèn)為三元運(yùn)算符的 “丑陋” 問(wèn)題,是開發(fā)者的編碼問(wèn)題,而不是語(yǔ)言問(wèn)題。三元在各種語(yǔ)言中很常見,它們是正常的,Go 語(yǔ)言也應(yīng)該要有。
- 認(rèn)為用 if-else 替代三元運(yùn)算符也很麻煩,讓開發(fā)者多讀了 3-4 行和額外的縮進(jìn)級(jí)別。
同意
認(rèn)可這個(gè)決策的也有不少,為此給出了大量的真實(shí)工程案例。
一般來(lái)講,我們用三元運(yùn)算符是希望這么用:
cond???true_value?:?false_value
你可能見過(guò)這么用:
cond???value_a?+?value_b?:?value_c?*?value_d
還見過(guò)這樣:
(((cond_a???val_one)?:?cond_b)???val_two)?:?val_three cond_a???(val_one?:?(cond_b???(val_two?:?val_three)))
還能嵌套三元運(yùn)算符:
int?a?=?cond_a???val_one?: ????cond_b???val_two?: ????cond_c???val_three?:?val_four;
也能出現(xiàn)可讀性更差的:
void?rgb_to_lightness_( ??const?double?re,?const?double?gr,?const?double?bl,?double?&li) { ??li=((re?<?gr)???((gr?<?bl)???bl?:?gr)?:?((re?<?bl)???bl?:?re)?+ ????????????????????????????(gr?<?re) ????????????????????????????((bl?<?gr)???bl?:?gr) ??????????????????????????:?((bl?<?re)???bl?:?re))?/?2.0; }
說(shuō)白了就是真實(shí)的代碼工程中,大家見到過(guò)大量三元運(yùn)算符濫用的場(chǎng)景,紛紛給出了大量的難理解的例子,讓大家困擾不堪。
總結(jié)
在這篇文章中,首先針對(duì) “三元運(yùn)算符” 做了基本的介紹。緊接著根據(jù) Go 語(yǔ)言不支持三元的態(tài)度進(jìn)行了說(shuō)明,且面向社區(qū)的爭(zhēng)議我們分為了正反方面的基本詮釋。
實(shí)際上一個(gè)簡(jiǎn)單的 ?:
既整潔又實(shí)用,但是沒(méi)有很好又高效的辦法方法可以防止丑陋的嵌套,也就是排除可讀性的問(wèn)題。
在真實(shí)的業(yè)務(wù)工程中,常常能看到一個(gè)三元運(yùn)算符,一開始只是很簡(jiǎn)單。后面嵌套越加越深,邏輯越寫越復(fù)雜,從而帶來(lái)了許多維護(hù)上的問(wèn)題。
給大家拋出如下問(wèn)題:
- 你認(rèn)為 Go 語(yǔ)言是否要有三元運(yùn)算符呢?
- 如果要有,復(fù)雜嵌套的三元運(yùn)算符又如何考慮呢?
以上問(wèn)題留給大家思考,更多關(guān)于Go 三元運(yùn)算符的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang中切片長(zhǎng)度和容量的區(qū)別示例詳解
切片長(zhǎng)度與容量在Go中很常見,切片長(zhǎng)度是切片中可用元素的數(shù)量,而切片容量是從切片中第一個(gè)元素開始計(jì)算的底層數(shù)組中的元素?cái)?shù)量,這篇文章主要給大家介紹了關(guān)于Golang中切片長(zhǎng)度和容量區(qū)別的相關(guān)資料,需要的朋友可以參考下2024-01-01Golang使用Zookeeper實(shí)現(xiàn)分布式鎖
分布式鎖是一種在分布式系統(tǒng)中用于控制并發(fā)訪問(wèn)的機(jī)制,ZooKeeper?和?Redis?都是常用的實(shí)現(xiàn)分布式鎖的工具,本文就來(lái)使用Zookeeper實(shí)現(xiàn)分布式鎖,希望對(duì)大家有所幫助2024-02-02Go語(yǔ)言sync.Map詳解及使用場(chǎng)景
Go語(yǔ)言中的sync.Map是一個(gè)高效的并發(fā)安全映射結(jié)構(gòu),適用于高并發(fā)讀多寫少的場(chǎng)景,它通過(guò)讀寫分離、無(wú)鎖讀取路徑、寫入時(shí)的鎖保護(hù)等機(jī)制,提高了讀取性能并減少了鎖競(jìng)爭(zhēng),sync.Map不需要手動(dòng)管理鎖,降低了編程復(fù)雜性,適合需要簡(jiǎn)單并發(fā)訪問(wèn)的場(chǎng)合2024-10-10Go select 死鎖的一個(gè)細(xì)節(jié)
這篇文章主要給大家分享的是Go select 死鎖的一個(gè)細(xì)節(jié),文章先是對(duì)主題提出問(wèn)題,然后展開內(nèi)容,感興趣的小伙伴可以借鑒一下,希望對(duì)你有所幫助2021-10-10Golang實(shí)現(xiàn)自己的orm框架實(shí)例探索
這篇文章主要為大家介紹了Golang實(shí)現(xiàn)自己的orm框架實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01