golang如何實(shí)現(xiàn)三元運(yùn)算符功能
今天來聊聊在 Go 語言中如何實(shí)現(xiàn)類似三元運(yùn)算符的功能。
首先,什么是三元運(yùn)算符?
在其他一些編程語言中,如 C 語言,三元運(yùn)算符是一種可以用一行代碼實(shí)現(xiàn)條件選擇的簡便方法。
x = condition ? a : b; // condition = true 則 x = a,否則 x = b
大道至簡的 Go 中肯定是沒有這個(gè)運(yùn)算符。
今天這篇文章將會就此展開,介紹 Go 中三元運(yùn)算符的一些實(shí)踐。
讓我們正式開始吧。
使用 if-else 語句
三元運(yùn)算符,本質(zhì)上其實(shí)就是 if-else
的簡化版本。通過 if-else
實(shí)現(xiàn)自然就是最常用的做法。
var x int if condition { x = a } else { x = b }
非常簡單且易理解,無心智負(fù)擔(dān)。畢竟,這就應(yīng)該是它本來的樣子。
雖然這比三元運(yùn)算符要長一些,但它更容易理解,也是 Go 所推薦的方式。
一行表達(dá)式
三元運(yùn)算符之所以被人喜愛,我覺得重要的一個(gè)原因就是:它足夠簡潔。我們只要一行代碼就實(shí)現(xiàn)條件判斷。
在 Go 中,如果想在一行代碼實(shí)現(xiàn),可能嗎?
我們先來看看 rust 和 Python 是如何實(shí)現(xiàn)的。
如果了解 rust,你可能看過如下代碼。
let x = { if condition { a } else { b } };
如上的代碼中,我們創(chuàng)建了一個(gè)代碼塊,它的最后一個(gè)表達(dá)式會作為 x
的值。這是 rust 所支持的語法。其實(shí)現(xiàn)代的不少語言支持這種簡約語法。
或者更簡潔下寫法也可以,如下:
let = if condition {a} else
如果你了解 Python,你可能看到這樣的代碼。
x = a if condition else b
是不是更加簡潔。
Go 不支持這樣的語法,我們要實(shí)現(xiàn)類似效果,就只能通過立刻執(zhí)行的匿名函數(shù)實(shí)現(xiàn)。
代碼如下:
x := func() int { if condition { return a } return b }()
算了,好丑,太麻煩了!
看起來還是 if-else
好用。但我還是不甘心,還是希望實(shí)現(xiàn)一行代碼的效果,怎么辦呢?
If 函數(shù)
前面的示例中,我們通過匿名函數(shù)實(shí)現(xiàn)類似于三元運(yùn)算符的功能。那不是說,預(yù)實(shí)現(xiàn)一個(gè)函數(shù)即可?
讓我們寫一個(gè) If
的函數(shù)來模擬三元運(yùn)算符。這個(gè)函數(shù)接收一個(gè)布爾值和兩個(gè)可能的返回值。根據(jù)布爾值的真假,它返回其中一個(gè)值。
代碼如下所示:
func If(condition bool, a, b int) int { if condition { return a } return b } x := If(3 > 2, x1, x2)
現(xiàn)在的代碼是不是就清晰了許多呢?
但這種方法還是有個(gè)缺點(diǎn),就是針對不同的類型都要實(shí)現(xiàn)一個(gè) If
函數(shù),如 IfInt()
、IfString()
、IfFloat()
等等。
不過從 Go 1.18 開始,Go 成功引入泛型。
我們可以通過泛型擴(kuò)展一個(gè)更通用的 If 函數(shù),不僅僅適用于整數(shù),還可以用于其他類型。
示例代碼如下:
func If[T any](condition bool, a, b T) T { if condition { return a } return b } func main() { x := 10 result := If(x > 0, "positive", "negative") fmt.Println(result) // 輸出 "positive" }
當(dāng)然,我也不是建議這么用。既然官方不支持就算了吧,if-else 多寫幾行就多寫幾行吧。
奇淫巧技:基于 map
在網(wǎng)上,我還發(fā)現(xiàn)了一個(gè)奇淫巧技:基于 Map 模擬三元運(yùn)算法。
代碼如下:
x = map[string]int{ true: b, false: c, }[a]
基于 true
和 false
實(shí)現(xiàn)條件判斷。
這方法看起來挺有創(chuàng)意,但這其實(shí)會增加代碼的理解成本,降低可讀性。再者,這種方法的效率是沒有 if-else
的效率高的,因?yàn)樯婕暗搅?map 的算法實(shí)現(xiàn),沒有那么直接。
為什么 Go 沒有三元運(yùn)算符
你是否好奇,為什么 Go 語言沒有三元運(yùn)算符?
官方認(rèn)為三元運(yùn)算符有時(shí)會讓代碼變得復(fù)雜和難以理解。Go 鼓勵(lì)寫出更清晰直接的代碼。
一個(gè) C 語言版本的復(fù)雜三元運(yùn)算符示例代碼:
#include <stdio.h> int main() { int x = 5, y = 10, z = 15; char *result; result = x > y ? "X" : y > z ? "Y" : z > x ? "Z" : x == y ? "X equals Y" : y == z ? "Y equals Z" : x == z ? "X equals Z" : "All equal"; printf("%s\n", result); return 0; }
看這個(gè)代碼,頭暈沒?
我們看看摘自官方文檔的原文:
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.
翻譯內(nèi)容:
Go 語言中沒有 ?: 運(yùn)算符的原因是,該語言的設(shè)計(jì)者們觀察到這種運(yùn)算符過于頻繁地被用來創(chuàng)建難以理解的復(fù)雜表達(dá)式。盡管 if-else 形式更長,但它無疑更清晰。一種語言只需要一種條件控制流構(gòu)造。
從 rust 和 python 的決策上也可看出,這個(gè)觀點(diǎn)得到了很多人的認(rèn)同。但與 Go 不同的是,rust 和 python 雖然不支持傳統(tǒng)的三元運(yùn)算符,它們都提供了其他簡潔的寫法。
不禁思考:Go 強(qiáng)調(diào)大道至簡。但 rust 和 python 其實(shí)也挺簡單的,保留了三運(yùn)算法符簡潔性的優(yōu)點(diǎn)。
總結(jié)
本文介紹 Go 中三元運(yùn)算符的最佳實(shí)踐。我們通過 if-else
語句或立即執(zhí)行的匿名函數(shù)等方式來實(shí)現(xiàn)類似的功能。
除此以外,可以根據(jù)你的需要和你覺得哪種方法更容易理解來選擇使用。
以上就是golang如何實(shí)現(xiàn)三元運(yùn)算符功能的詳細(xì)內(nèi)容,更多關(guān)于go三元運(yùn)算符的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
gorm update傳入struct對象,零值字段不更新的解決方案
這篇文章主要介紹了gorm update傳入struct對象,零值字段不更新的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04go語言Pflag Viper Cobra 核心功能使用介紹
這篇文章主要為大家介紹了go語言Pflag Viper Cobra 核心功能使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Go語言常見數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)詳解
這篇文章主要為大家學(xué)習(xí)介紹了Go語言中的常見數(shù)據(jù)結(jié)構(gòu)(channal、slice和map)的實(shí)現(xiàn),文中的示例代碼簡潔易懂,需要的可以參考一下2023-07-07golang使用sync.singleflight解決熱點(diǎn)緩存穿透問題
在go的sync包中,有一個(gè)singleflight包,里面有一個(gè)?singleflight.go文件,代碼加注釋,一共200行出頭,通過?singleflight可以很容易實(shí)現(xiàn)緩存和去重的效果,避免重復(fù)計(jì)算,接下來我們就給大家詳細(xì)介紹一下sync.singleflight如何解決熱點(diǎn)緩存穿透問題2023-07-07簡單聊聊Golang中defer預(yù)計(jì)算參數(shù)
在golang當(dāng)中defer代碼塊會在函數(shù)調(diào)用鏈表中增加一個(gè)函數(shù)調(diào)用,下面這篇文章主要給大家介紹了關(guān)于Golang中defer預(yù)計(jì)算參數(shù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03