欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang中為什么不存在三元運算符詳解

 更新時間:2020年09月04日 14:44:02   作者:apocelipes  
這篇文章主要給大家介紹了關(guān)于golang中為什么不存在三元運算符的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

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

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中不存在?這個運算符,編譯器不認(rèn)識而且非字母數(shù)字下劃線也不能用做變量名,自然也就當(dāng)作是非法字符了。

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

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中不存在?:運算符的原因是因為語言設(shè)計者已經(jīng)預(yù)見到三元運算符經(jīng)常被用來構(gòu)建一些極其復(fù)雜的表達(dá)式。雖然使用if進(jìn)行替代會讓代碼顯得更長,但這毫無疑問可讀性更強(qiáng)。一個語言只需要有一種條件判斷結(jié)構(gòu)就足夠了。

毫無疑問,這是在golang“大道至簡”的指導(dǎo)思想下的產(chǎn)物。

這段話其實沒問題,因為某些三元運算符的使用場景確實會降低代碼的可讀性:

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';

乍一看確實很復(fù)雜,至少第二個表達(dá)式不花個20秒細(xì)看可能沒法理清控制流程(想象一下當(dāng)縮進(jìn)錯位或是完全沒有縮進(jìn)的時候)。

如果把它們直接轉(zhuǎn)化成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其實可以看作是變量的默認(rèn)值,于是代碼可以這么寫:

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來清除嵌套結(jié)構(gòu):

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'
}

現(xiàn)在再來看,顯然使用if語句的版本的可讀性更高,邏輯也更清晰(通過去除嵌套)。

然而事實也不盡然。除了用三元運算符表達(dá)流程控制之外,事實上更常見更廣泛的一個應(yīng)用是如下這樣的表達(dá)式:

const val = expr ? trueValue : falseValue

const func = (age) => age > 18 ? '成年人' : '未成年人'

類似上述通過一個簡短的條件表達(dá)式來確定變量的值,在開發(fā)中的出現(xiàn)頻率是相當(dāng)高的。這時三元運算符的意圖更清晰,可讀性也較if語句更高,特別是配合匿名函數(shù)(lambda表達(dá)式)使用可以極大簡化我們的代碼。

對此python的解決之道是之支持上述的簡化版三元表達(dá)式,同時表達(dá)式不支持嵌套,達(dá)到了揚長避短的目的。不過代價是編譯器的相關(guān)實現(xiàn)會復(fù)雜化。

而對于golang來說一個簡單的能只通過單遍掃描即可完成ast構(gòu)建的編譯器是其保持急速的構(gòu)建速度的秘訣之一,為了這樣簡單的功能增加編譯器實現(xiàn)的復(fù)雜度是不可接受的。同時由于golang“大道至簡”的哲學(xué),能用現(xiàn)有語法結(jié)構(gòu)解決的問題,自然不會再添加新的語法。

不過還是有辦法的,雖然不推薦:

func If(cond bool, a, b interface{}) {
  if cond {
    return a
  }

  return b
}

age := 20
val := If(age > 18, "成年人", "未成年人").(string)

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

  1. 使用接口導(dǎo)致性能下降
  2. 需要強(qiáng)制的類型斷言
  3. 不管三元表達(dá)式還是if語句,對于不會到達(dá)的分支是不會計算的,也就是惰性計算;而給函數(shù)傳遞參數(shù)時每一個表達(dá)式都會被計算

最后總結(jié)一下:

三元運算符的優(yōu)點:

  • 對于簡短的表達(dá)式使用三元運算符表意更清晰,特別是在習(xí)慣了線性閱讀三元運算符表達(dá)式之后
  • 不需要中間狀態(tài)(例如第一個例子中的let變量可以替換為const,代碼更健壯),心智負(fù)擔(dān)更低
  • 沒有中間狀態(tài)也就意味著更少或完全沒有副作用,代碼更易跟蹤和維護(hù)

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

  • 對于復(fù)雜邏輯代碼可讀性較差(例如第一個例子中的status,需要在trueValue的位置進(jìn)行進(jìn)一步的條件判斷時)
  • 容易被濫用,很多人將其用于替代if語句或是簡化復(fù)雜的if嵌套,這會導(dǎo)致上一條中所描述的結(jié)果
  • 條件分支只能為表達(dá)式,不支持多條語句

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

參考

https://juejin.im/post/6844903561759850510

https://www.it-swarm.dev/zh/javascript/替代js中的嵌套三元運算符/1055944752/

https://golang.org/doc/faq#Does_Go_have_a_ternary_form

總結(jié)

到此這篇關(guān)于golang中為什么不存在三元運算符的文章就介紹到這了,更多相關(guān)golang不存在三元運算符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go實現(xiàn)一個配置包詳解

    Go實現(xiàn)一個配置包詳解

    在現(xiàn)代軟件開發(fā)中,配置文件是不可或缺的一部分。在編寫 Go 項目時,程序的靈活性和可擴(kuò)展性都需要依賴于配置文件的加載。本文就來探究下在 Go 項目中如何更加方便的加載和管理配置,感興趣的朋友跟著小編一起來學(xué)習(xí)吧
    2023-04-04
  • go語言中sort包的實現(xiàn)方法與應(yīng)用詳解

    go語言中sort包的實現(xiàn)方法與應(yīng)用詳解

    golang中也實現(xiàn)了排序算法的包sort包,所以下面這篇文章主要給大家介紹了關(guān)于go語言中sort包的實現(xiàn)方法與應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 淺談Go語言的高效編碼細(xì)節(jié)

    淺談Go語言的高效編碼細(xì)節(jié)

    這篇文章主要介紹了淺談Go語言的高效編碼細(xì)節(jié),我們都知道golang是天生的高并發(fā),高效的編譯型語言,可我們也都可知道,工具再好,用法不對,全都白費,我們來舉2個常用路徑來感受一下
    2023-01-01
  • Golang 實現(xiàn) Redis系列(六)如何實現(xiàn) pipeline 模式的 redis 客戶端

    Golang 實現(xiàn) Redis系列(六)如何實現(xiàn) pipeline 模式的 redis 客戶端

    pipeline 模式的 redis 客戶端需要有兩個后臺協(xié)程負(fù)責(zé) tcp 通信,調(diào)用方通過 channel 向后臺協(xié)程發(fā)送指令,并阻塞等待直到收到響應(yīng),本文是使用 golang 實現(xiàn) redis 系列的第六篇, 將介紹如何實現(xiàn)一個 Pipeline 模式的 Redis 客戶端。
    2021-07-07
  • go常用指令之go?mod詳解

    go常用指令之go?mod詳解

    當(dāng)go命令運行時,它查找當(dāng)前目錄然后查找相繼的父目錄來找出 go.mod,下面這篇文章主要給大家介紹了關(guān)于go常用指令之go?mod的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Golang中Channel實戰(zhàn)技巧與一些說明

    Golang中Channel實戰(zhàn)技巧與一些說明

    channel是Go語言內(nèi)建的first-class類型,也是Go語言與眾不同的特性之一,下面這篇文章主要給大家介紹了關(guān)于Golang中Channel實戰(zhàn)技巧與一些說明的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • GoFrame通用類型變量gvar與interface基本使用對比

    GoFrame通用類型變量gvar與interface基本使用對比

    這篇文章主要為大家介紹了GoFrame通用類型變量gvar與interface基本使用對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語言并發(fā)之Sync包的6個關(guān)鍵概念總結(jié)

    Go語言并發(fā)之Sync包的6個關(guān)鍵概念總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Go語言并發(fā)中Sync包的6個關(guān)鍵概念,文中的示例代碼講解詳細(xì),對我們深入學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下
    2023-05-05
  • 十個Go map面試??紗栴}合集

    十個Go map面試??紗栴}合集

    go面試中,map相關(guān)知識點問的比較多,這篇文章主要為大家整理歸納了10個??嫉膯栴},文中的示例代碼講解詳細(xì),希望對大家有一定的幫助
    2023-07-07
  • 如何使用Golang發(fā)送Get和Post請求

    如何使用Golang發(fā)送Get和Post請求

    這篇文章主要給大家介紹了關(guān)于如何使用Golang發(fā)送Get和Post請求的相關(guān)資料,Go語言(Golang)的標(biāo)準(zhǔn)庫提供了處理HTTP請求的功能,這使得將Go用于web應(yīng)用程序變得非常容易,需要的朋友可以參考下
    2023-06-06

最新評論