摘要:本文會從書寫方法使用場景實現(xiàn)原理以及優(yōu)缺點等各方面剖析關(guān)鍵字。原理源碼在語言代碼庫中,只有一句定義語句,位于內(nèi)建文件中是一個預(yù)聲明的標(biāo)識符,它的值是。在常量聲明中,作為當(dāng)前代碼塊中的整數(shù)序數(shù)。
iota 是 Go 語言的一個保留字,用作常量計數(shù)器。由于 iota 具有自增特性,所以可以簡化數(shù)字增長的常量定義。
iota 是一個具有魔法的關(guān)鍵字,往往令初學(xué)者難以理解其原理和使用方法。
本文會從書寫方法、使用場景、實現(xiàn)原理以及優(yōu)缺點等各方面剖析 iota 關(guān)鍵字。?
正確寫法:
const ( FirstItem = iota SecondItem ThirdItem)// 或者const SingleItem = iota
錯誤寫法:
var FirstItem = iota// 或者println(iota)
iota 只能用于常量表達(dá)式,而且必須在 const 代碼塊中出現(xiàn),不允許出現(xiàn)在其它位置。
?
iota 的主要使用場景用于枚舉。Go 語言的設(shè)計原則追求極盡簡化,所以沒有枚舉類型,沒有 enum關(guān)鍵字。
Go 語言通常使用常量定義代替枚舉類型,于是 iota 常常用于其中,用于簡化代碼。
例如:
package mainconst ( B = 1 << (10 * iota) // 1 << (10*0) KB // 1 << (10*1) MB // 1 << (10*2) GB // 1 << (10*3) TB // 1 << (10*4) PB // 1 << (10*5) EB // 1 << (10*6) ZB // 7 << (10*5))func main() { println(B, KB, MB, GB, TB)}
輸出結(jié)果:
1 1024 1048576 1073741824
我們也可以直接這樣書寫這段代碼:
const ( B = 1 KB = 1024 MB = 1048576 GB = 1073741824 ... )
兩段代碼對比來看,使用 iota 的代碼顯然簡潔優(yōu)雅很多。不使用 iota 的代碼,對于代碼潔癖者來說,簡直就是一坨,不可接受。
而 Go 語言的發(fā)明者,恰恰具有代碼潔癖,而且還是深度潔癖。Go 語言設(shè)計初衷之一:追求簡潔優(yōu)雅。?
iota 源碼在 Go 語言代碼庫中,只有一句定義語句,位于內(nèi)建文件 go/src/builtin/builtin.go 中:
const iota = 0 // Untyped int.
iota 是一個預(yù)聲明的標(biāo)識符,它的值是 0。 在 const 常量聲明中,作為當(dāng)前 const 代碼塊中的整數(shù)序數(shù)。
從 Go 語言代碼庫的代碼看,iota 只是一個簡單的整數(shù) 0,為什么能夠作為常量計數(shù)器,進(jìn)行常量自增呢?它的源碼到底在哪里?
我們做一個小試驗,就會理解其中的道理,看一段代碼:
package mainconst ( FirstItem = iota SecondItem ThirdItem)func main() { println(FirstItem) println(SecondItem) println(ThirdItem)}
非常簡單,就是打印 FirstItem,SecondItem,ThirdItem。
編譯上述代碼:
go tool compile -N -l main.go
使用 -N -l 編譯參數(shù)用于禁止內(nèi)聯(lián)和優(yōu)化,防止編譯器優(yōu)化和簡化代碼,弄亂次序。這樣便于閱讀匯編代碼。
導(dǎo)出匯編代碼:
go tool objdump main.o
截取部分結(jié)果如下:
TEXT %22%22.main(SB) gofile../Users/wangzebin/test/test/main.go...main.go:10 MOVQ $0x0, 0(SP) // 對應(yīng)源碼 println(FirstItem)main.go:10 CALL 0x33b [1:5]R_CALL:runtime.printint...main.go:11 MOVQ $0x1, 0(SP) // 對應(yīng)源碼 println(SecondItem)main.go:11 CALL 0x357 [1:5]R_CALL:runtime.printint...main.go:11 MOVQ $0x2, 0(SP) // 對應(yīng)源碼 println(ThirdItem)main.go:11 CALL 0x373 [1:5]R_CALL:runtime.printint...
編譯之后,對應(yīng)的常量 FirstItem、SecondItem 和 ThirdItem,分別替換為$0x0、$0x1 和 $0x2。
這說明:Go代碼中定義的常量,在編譯時期就會被替換為對應(yīng)的常量。當(dāng)然 iota,也不可避免地在編譯時期,按照一定的規(guī)則,被替換為對應(yīng)的常量。
所以,Go 語言源碼庫中是不會有 iota 源碼了,它的魔法在編譯時期就已經(jīng)施展完畢。也就是說,解釋 iota 的代碼包含在 go 這個命令和其調(diào)用的組件中。
如果你要閱讀它的源碼,準(zhǔn)確的說,閱讀處理 iota 關(guān)鍵字的源碼,需要到 Go 工具源碼庫中尋找,而不是 Go 核心源碼庫。
?
使用 iota,雖然可以書寫簡潔優(yōu)雅的代碼,但對于不熟悉規(guī)則的人來講,又帶來的很多不必要的麻煩和誤解。
對于引入 iota,到底好是不好,每個人都有自己的評價。實際上,有些不常用的寫法,甚至有些賣弄編寫技巧的的寫法,并不是設(shè)計者的初衷。
大多數(shù)情況下,我們還是使用最簡單最明確的寫法,iota 只是提供了一種選擇而已。一個工具使用的好壞,取決于使用它的人,而不是工具本身。
以下是 iota 編譯規(guī)則:
iota 依賴于 const 關(guān)鍵字,每次新的 const 關(guān)鍵字出現(xiàn)時,都會讓 iota 初始化為0。
const a = iota // a=0const ( b = iota // b=0 c // c=1)
iota 按行遞增加 1。
const ( a = iota // a=0 b // b=1 c // c=2)
同一 const 塊出現(xiàn)多個 iota,只會按照行數(shù)計數(shù),不會重新計數(shù)。
const ( a = iota // a=0 b = iota // b=1 c = iota // c=2 )
與上面的代碼完全等同,b 和 c 的 iota 通常不需要寫。
空行在編譯時期首先會被刪除,所以空行不計數(shù)。
const ( a = iota // a=0 b // b=1 c // c=2 )
占位 "_",它不是空行,會進(jìn)行計數(shù),起到跳值作用。
const ( a = iota // a=0 _ // _=1 c // c=2 )
開頭插隊會進(jìn)行計數(shù)。
const ( i = 3.14 // i=3.14 j = iota // j=1 k = iota // k=2 l // l=3)
中間插隊會進(jìn)行計數(shù)。
const ( i = iota // i=0 j = 3.14 // j=3.14 k = iota // k=2 l // l=3)
一行多個iota,分別計數(shù)。
const ( i, j = iota, iota // i=0,j=0 k, l // k=1,l=1)
參考資料:
1. go語言編程
2. 編程寶庫
?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/123643.html
摘要:語言中變量的聲明必須使用空格隔開如可見性規(guī)則語言中,使用大小寫來決定該常量變量類型接口結(jié)構(gòu)或函數(shù)是否可以被外部包所調(diào)用。 一.Go 語言的基礎(chǔ)組成有以下幾個部分: 1.包聲明 2.引入包 3.函數(shù) 4.變量 5.語句 & 表達(dá)式 6.注釋 // 當(dāng)前程序的包名 package main // 導(dǎo)入其他包 import . fmt // 常量定義 const PI = 3.14 ...
摘要:代碼分析參考博客源碼分析下載源碼可以從上下載編譯環(huán)境代碼下載到任意目錄,這里是設(shè)置環(huán)境變量,這里為這個目錄名很重要,的包都是以這個為基礎(chǔ)的鏈接到源碼目錄即可通過編譯 [TOC] minikube代碼分析 參考博客: minikube 源碼分析 下載 minikube源碼可以從github上下載: git clone [email protected]:kubernetes/minikube....
摘要:中的設(shè)計非常輕量,又兼具很高的擴展性,初學(xué)者都可以輕易的設(shè)計出自定義的路由功能,使用上十分簡單這里來吐槽一下的,雖然我也對愛得深沉,下面請看的。一般網(wǎng)站的路由規(guī)則太多了,編寫繁瑣,可以通過的方法進(jìn)行一種簡化。????由于本人之前一直是Java Coder,在Java web開發(fā)中其實大家都很依賴框架,所以當(dāng)在學(xué)習(xí)Golang的時候,自己便想著在Go開發(fā)中脫離框架,自己動手造框架來練習(xí)。通過學(xué)...
摘要:中的設(shè)計非常輕量,又兼具很高的擴展性,初學(xué)者都可以輕易的設(shè)計出自定義的路由功能,使用上十分簡單這里來吐槽一下的,雖然我也對愛得深沉,下面請看的。一般網(wǎng)站的路由規(guī)則太多了,編寫繁瑣,可以通過的方法進(jìn)行一種簡化。????由于本人之前一直是Java Coder,在Java web開發(fā)中其實大家都很依賴框架,所以當(dāng)在學(xué)習(xí)Golang的時候,自己便想著在Go開發(fā)中脫離框架,自己動手造框架來練習(xí)。通過學(xué)...
閱讀 3490·2021-11-17 17:00
閱讀 3868·2021-08-09 13:46
閱讀 2894·2019-08-30 15:54
閱讀 672·2019-08-30 13:54
閱讀 2973·2019-08-29 17:13
閱讀 3264·2019-08-29 14:00
閱讀 3016·2019-08-29 11:11
閱讀 1433·2019-08-26 10:15