Iota is a reserved word of the Go language and is used as a constant counter. Since iota has self increasing characteristics, the constant definition of digital growth can be simplified.
iota is a magic keyword, which often makes it difficult for beginners to understand its principle and usage.
This paper will analyze iota keywords from the aspects of writing methods, usage scenarios, implementation principles, advantages and disadvantages.
1. Writing method
Correct writing:
const ( FirstItem = iota SecondItem ThirdItem ) // perhaps const SingleItem = iota
Incorrect writing:
var FirstItem = iota // perhaps println(iota)iota
It can only be used for constant expressions, and must appear in const code block. It is not allowed to appear in other places.
2. Usage scenario
The main usage scenarios of iota are for enumeration. The design principle of Go language pursues extreme simplification, so there is no enumeration type and no enum keyword.
Go languages often use constant definitions instead of enumeration types, so iota is often used to simplify code.
For example:
package main const ( 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) }
Output results:
1 1024 1048576 1073741824
We can also write this code directly as follows:
const ( B = 1 KB = 1024 MB = 1048576 GB = 1073741824 ... )
Comparing the two pieces of code, the code using iota is obviously much simpler and more elegant. Code that does not use iota is simply a lump and unacceptable to code purists.
The inventor of the Go language has a code cleanliness mania, and it is also a deep cleanliness mania. One of the original intentions of Go language design: the pursuit of simplicity and elegance.
3. iota principle
The iota source code has only one definition statement in the Go language code base, which is located in the built-in file go/src/builtin/builtin.go:
const iota = 0 // Untyped int.iota
Is a pre declared identifier with a value of 0. In const constant declaration, it is an integer ordinal in the current const code block.
From the code of the Go language code base, iota is just a simple integer 0. Why can it be used as a constant counter for constant self increment? Where is its source code?
If we do a small experiment, we will understand the truth and look at a piece of code:
package main const ( FirstItem = iota SecondItem ThirdItem ) func main() { println(FirstItem) println(SecondItem) println(ThirdItem) }
Very simple, that is, print FirstItem, SecondItem and ThirdItem.
Compile the above code:
go tool compile -N -l main.go
The - N -l compilation parameter is used to prohibit inlining and optimization, prevent the compiler from optimizing and simplifying the code and confusing the order. This makes it easy to read assembly code.
Export assembly code:
go tool objdump main.o
The interception results are as follows:
TEXT %22%22.main(SB) gofile../Users/wangzebin/test/test/main.go ... main.go:10 MOVQ $0x0, 0(SP) // Corresponding source code println(FirstItem) main.go:10 CALL 0x33b [1:5]R_CALL:runtime.printint ... main.go:11 MOVQ $0x1, 0(SP) // Corresponding source code println(SecondItem) main.go:11 CALL 0x357 [1:5]R_CALL:runtime.printint ... main.go:11 MOVQ $0x2, 0(SP) // Corresponding source code println(ThirdItem) main.go:11 CALL 0x373 [1:5]R_CALL:runtime.printint ...
After compilation, the corresponding constants FirstItem, SecondItem and ThirdItem are replaced with $0x0, $0x1 and $0x2 respectively.
This indicates that the constants defined in the Go code will be replaced with the corresponding constants at compile time. Of course, iota is inevitably replaced with the corresponding constant according to certain rules during compilation.
Therefore, there will be no iota source code in the go language source code library. Its magic has been performed during compilation. That is, the code that interprets iota is contained in the go command and the components it invokes.
If you want to read its source code, to be exact, to read the source code dealing with iota keywords, you need to look in the Go tool source code library, not the Go core source code library.
4. iota rules
Using iota, although you can write concise and elegant code, it brings many unnecessary troubles and misunderstandings to people who are not familiar with the rules.
Everyone has their own evaluation on whether the introduction of iota is good or not. In fact, some unusual writing methods, and even some writing methods that show off writing skills, are not the original intention of the designer.
In most cases, we still use the simplest and most explicit way. iota only provides a choice. The use of a tool depends on the person who uses it, not the tool itself.
The following are the iota Compilation Rules:
1) Dependent const
Iota depends on the const keyword. Each time a new const keyword appears, iota will be initialized to 0.
const a = iota // a=0 const ( b = iota // b=0 c // c=1 )
2) Count by row
iota Add 1 by line. const ( a = iota // a=0 b // b=1 c // c=2 )
3) Multiple iota s
If multiple iota s appear in the same const block, they will only be counted according to the number of rows and will not be counted again.
const ( a = iota // a=0 b = iota // b=1 c = iota // c=2 )
Equivalent to the above code, b and c iota usually do not need to be written.
4) Blank line processing
Empty lines are first deleted at compile time, so empty lines are not counted.
const ( a = iota // a=0 b // b=1 c // c=2 )
5) Skip value occupation
The placeholder "", which is not an empty line, will count and play the role of value skipping.
const ( a = iota // a=0 _ // _=1 c // c=2 )
6) Jump in line at the beginning
Queue jumping at the beginning will be counted.
const ( i = 3.14 // i=3.14 j = iota // j=1 k = iota // k=2 l // l=3 )
7) Jump in the middle
The middle queue will be counted.
const ( i = iota // i=0 j = 3.14 // j=3.14 k = iota // k=2 l // l=3 )
8) Multiple iota s in a row
Multiple iota s in a row are counted separately.
const ( i, j = iota, iota // i=0,j=0 k, l // k=1,l=1 )
reference material: