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