在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Golang為何舍棄三元運算符

馬哥Linux運維 ? 來源:cnblogs ? 2024-04-03 15:13 ? 次閱讀

三元運算符廣泛存在于其他語言中,比如:

python

val = trueValue if expr else falseValue

javascript:

const val = expr ? trueValue : falseValue

c、c++

const char *val = expr ? "trueValue" : "falseValue";

然而,被廣泛支持的三目運算符在golang中卻是不存在的!如果我們寫出類似下面的代碼:

val := expr ? "trueValue" : "falseValue"

那么編譯器就該抱怨了:invalid character U+003F '?'。意思是golang中不存在?這個運算符,編譯器不認識而且非字母數字下劃線也不能用做變量名,自然也就當作是非法字符了。

然而這是為什么呢,其實官方給出了解釋,這里簡單引用一下:

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.

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)

不推薦這么做是有幾個原因:

使用接口導致性能下降

需要強制的類型斷言

不管三元表達式還是if語句,對于不會到達的分支是不會計算的,也就是惰性計算;而給函數傳遞參數時每一個表達式都會被計算

最后總結一下:

三元運算符的優點:

對于簡短的表達式使用三元運算符表意更清晰,特別是在習慣了線性閱讀三元運算符表達式之后

不需要中間狀態(例如第一個例子中的let變量可以替換為const,代碼更健壯),心智負擔更低

沒有中間狀態也就意味著更少或完全沒有副作用,代碼更易跟蹤和維護

但三元運算符也有明顯的缺點:

對于復雜邏輯代碼可讀性較差(例如第一個例子中的status,需要在trueValue的位置進行進一步的條件判斷時)

容易被濫用,很多人將其用于替代if語句或是簡化復雜的if嵌套,這會導致上一條中所描述的結果

條件分支只能為表達式,不支持多條語句

所以這是一個見仁見智的問題,總之只能入鄉隨俗了。

審核編輯:黃飛

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編譯器
    +關注

    關注

    1

    文章

    1634

    瀏覽量

    49132
  • 運算符
    +關注

    關注

    0

    文章

    172

    瀏覽量

    11084

原文標題:為什么golang中不存在三元運算符

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言運算符的使用方法

    詳細介紹了C語言表達式、算術運算符、賦值運算符、關系運算符、條件結構、邏輯運算符、位運算符的語法和使用方法,并討論了
    發表于 11-02 11:30 ?1621次閱讀
    C語言<b class='flag-5'>運算符</b>的使用方法

    如何去使用運算符

    運算的定義是什么?運算符是由什么組成的?如何去使用運算符
    發表于 07-15 13:13

    條件運算符是什么_條件運算符有哪些

    運算符優先級高于賦值、逗號運算符,低于其他運算符。關系運算實際上是邏輯比較運算,它是邏輯運算
    發表于 11-16 16:02 ?1.1w次閱讀
    條件<b class='flag-5'>運算符</b>是什么_條件<b class='flag-5'>運算符</b>有哪些

    單目運算符是什么_單目運算符有哪些

    單目運算符是指運算所需變量為一個的運算符,又叫一運算符,其中有邏輯非運算符:!、按位取反
    的頭像 發表于 02-24 15:42 ?6.1w次閱讀
    單目<b class='flag-5'>運算符</b>是什么_單目<b class='flag-5'>運算符</b>有哪些

    C運算符的優先級和結合性詳細解決

    運算符是一種告訴編譯器執行特定的數學或邏輯操作的符號。 C語言內置了豐富的運算符,大體可分為10類:算術運算符、關系運算符、邏輯運算符、位
    的頭像 發表于 02-22 17:27 ?3243次閱讀

    淺析MySQL中的各類運算符

    MySQL支持多種運算符,我們在寫SQL腳本時經常會需要用到各種各樣的運算符,這些運算符可以用來連接表達式,進而從數據庫中查詢我們需要的結果集等。這些類型主要包括算術運算符、比較
    的頭像 發表于 05-03 17:41 ?2059次閱讀
    淺析MySQL中的各類<b class='flag-5'>運算符</b>

    干貨:大實例講解種C++運算符重載

    本章節主要講解是運算符重載。運算符重載是賦予運算符能操作自定義類型的功能。C++運算符重載主要分為以下類:
    的頭像 發表于 09-30 16:59 ?3447次閱讀
    干貨:<b class='flag-5'>三</b>大實例講解<b class='flag-5'>三</b>種C++<b class='flag-5'>運算符</b>重載

    python運算符是什么

    python運算符 0. 什么是運算符? 本章節主要說明Python的運算符。舉個簡單的例子 4 +5 = 9 。 例子中,4和5被稱為操作數,“+”號為運算符。 Python語言支持
    的頭像 發表于 02-21 16:44 ?2387次閱讀

    SystemVerilog-運算符/表達式規則

    RTL建模中廣泛使用的運算符是條件運算符,也稱為三元運算符,該運算符用于在兩個表達式之間進行選擇——表5-2列出了用于表示條件
    的頭像 發表于 08-03 09:03 ?3128次閱讀

    如何靈活使用三元運算符

    給定四個無符號數,請找出最小值。無符號數可以與標準比較運算符(a < b)進行比較。使用條件運算符描述一個兩路的最小值電路,然后組合它來創建一個4路最小電路。可能需要一些線向量作為中間結果。
    的頭像 發表于 09-28 17:07 ?1302次閱讀

    什么是運算符重載

    重載運算符是具有特殊名稱的函數,是通過關鍵字** operator **后跟運算符的符號來定義的
    的頭像 發表于 01-20 15:30 ?2496次閱讀

    條件(三元運算符

    RTL建模中廣泛使用的運算符是條件運算符,也稱為三元運算符,該運算符用于在兩個表達式之間進行選擇——表5-2列出了用于表示條件
    的頭像 發表于 02-09 15:42 ?1365次閱讀
    條件(<b class='flag-5'>三元</b>)<b class='flag-5'>運算符</b>

    什么是移位運算符

    移位運算符將向量的位向右或向左移位指定的次數。SystemVerilog具有按位和算術移位運算符
    的頭像 發表于 02-09 15:49 ?1844次閱讀
    什么是移位<b class='flag-5'>運算符</b>

    Go語言運算符主要包括哪些呢?

    Go語言運算符主要包括:算數運算符、關系運算符、邏輯運算符、位運算符、賦值運算符和其他
    的頭像 發表于 05-26 15:54 ?869次閱讀
    Go語言<b class='flag-5'>運算符</b>主要包括哪些呢?

    c語言從右到左的運算符有哪些

    用在變量之后時,它們會先返回變量的原始值,然后再進行遞增或遞減。 三元條件運算符 ( ?: ):這個運算符的求值順序是從右到左。首先計算第個表達式,然后根據第一個表達式的結果選擇第二
    的頭像 發表于 08-20 11:39 ?961次閱讀
    主站蜘蛛池模板: 国产精品久久久久久久免费 | 亚洲xx网站| 日本.www| 午夜免费毛片| 看免费视频| 日本欧美一区二区三区免费不卡| 五月情婷婷| 日本番囗| 天天碰夜夜操| 俄罗斯一级特黄黄大片| 中文字幕亚洲一区二区三区| 国产69久久精品成人看| 色综合网天天综合色中文男男| 欧美日剧在线免费| 天天射日| 精品一区二区三区三区| 你懂的国产| 久热久操| 一 级 黄 色 片生活片| 国产精品特黄毛片| 日日碰狠狠添天天爽五月婷| 欧美在线黄| 一级一级毛片免费播放| 国模大胆一区二区三区| 狠狠干.com| 国产男女免费视频| 韩国三级床戏合集| 性夜影院爽黄a爽在线看香蕉| 色域综合| 手机看片福利视频| 伊人网99| 怡红院影院| 亚洲色网址| 深爱五月婷婷| 成人黄性视频| 成在线人永久免费播放视频| 四虎影院欧美| 国产成人在线播放视频| 国产在线观看黄色| 四虎最新影院| 日韩特黄|