亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang中為什么不存在三元運(yùn)算符詳解

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

三元運(yùn)算符廣泛存在于其他語(yǔ)言中,比如:

python:

val = trueValue if expr else falseValue

javascript:

const val = expr ? trueValue : falseValue

c、c++:

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

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

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

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

然而這是為什么呢,其實(shí)官方給出了解釋,這里簡(jiǎn)單引用一下:

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

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

這段話其實(shí)沒(méi)問(wèn)題,因?yàn)槟承┤\(yùn)算符的使用場(chǎng)景確實(shí)會(huì)降低代碼的可讀性:

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

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

如果把它們直接轉(zhuǎn)化成if語(yǔ)句是這樣的:

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

看起來(lái)并沒(méi)有多少的改善,特別是例2,三層嵌套,不管是誰(shuí)review到這段代碼難免不會(huì)抱怨你幾句。

然而事實(shí)上這些代碼是可以簡(jiǎn)化的,考慮到三元運(yùn)算符總是會(huì)給變量一個(gè)值,因此最后的else其實(shí)可以看作是變量的默認(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'
    }
  }
}

其次,對(duì)于例2,顯然可以使用else if來(lái)清除嵌套結(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)在再來(lái)看,顯然使用if語(yǔ)句的版本的可讀性更高,邏輯也更清晰(通過(guò)去除嵌套)。

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

const val = expr ? trueValue : falseValue

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

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

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

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

不過(guò)還是有辦法的,雖然不推薦:

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

  return b
}

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

不推薦這么做是有幾個(gè)原因:

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

最后總結(jié)一下:

三元運(yùn)算符的優(yōu)點(diǎn):

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

但三元運(yùn)算符也有明顯的缺點(diǎn):

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

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

參考

https://juejin.im/post/6844903561759850510

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

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

總結(jié)

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

相關(guān)文章

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

    Go實(shí)現(xiàn)一個(gè)配置包詳解

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

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

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

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

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

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

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

    go常用指令之go?mod詳解

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

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

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

    GoFrame通用類型變量gvar與interface基本使用對(duì)比

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

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

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

    十個(gè)Go map面試??紗?wèn)題合集

    go面試中,map相關(guān)知識(shí)點(diǎn)問(wèn)的比較多,這篇文章主要為大家整理歸納了10個(gè)常考的問(wèn)題,文中的示例代碼講解詳細(xì),希望對(duì)大家有一定的幫助
    2023-07-07
  • 如何使用Golang發(fā)送Get和Post請(qǐng)求

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

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

最新評(píng)論