This article has participated in the Denver Nuggets Creators Camp 3 “More Productive writing” track, see details: Digg project | creators Camp 3 ongoing, “write” personal impact.
We know that iota is often used in const expressions, where the value starts at 0 and +1 for each additional line.
Iota can simplify the definition of constants, and the rules will be introduced in a few warm-up exercises to see how well you understand ioTA.
The title
- What is the value of each of the following constants?
type Priority int
const (
LOG_EMERG Priority = iota
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
)
Copy the code
The code comes from the log module, and the LOG_EMERG value is 0, incrementing each of the following constants by 1.
- What is the value of each of the following constants?
const (
mutexLocked = 1 << iota // mutex is locked
mutexWoken
mutexStarving
mutexWaiterShift = iota
starvationThresholdNs = 1e
)
Copy the code
The code is derived from an implementation of the Go Mutex to indicate address offsets for various status bits.
The answer:
mutexLocked == 1; mutexWoken ==2; mutexStarving ==4; mutexWaiterShift ==3; starvationThresholdNs ==1000000
Copy the code
- What is the value of each of the following constants?
const (
bit0, mask0 = 1 << iota.1<<iota - 1
bit1, mask1
_, _
bit3, mask3
)
Copy the code
The answer:
bit0 == 1, mask0 = =0, bit1 = =2, mask1 = =1, bit3 = =8, mask3 = =7
Copy the code
Iota rules
Many information introduction rules are:
- Iota is reset to 0 when the const keyword is present;
- The ioTA value increases by 1 for each new line in the const declaration block.
Iota represents the row index of a const block (subscript 0).
Another important feature of const declarations is that the first constant must specify an expression, and subsequent constants inherit the expression if they do not have one.
So, let’s look at the code above:
const (
bit0, mask0 = 1 << iota.1<<iota - 1 //const iota==0 on line 0
bit1, mask1 Const iota==1, iota==1, iota==1
_, _ Const iota==2 on line 2
bit3, mask3 //const iota==3
)
Copy the code
Resolution:
- Bit0, mask0 = 1<<0, 1<< 0-1, so bit0 == 1, mask0 == 0;
- 1 << 0 is to shift 1 in base 2 by 0 bits to the left, the result is still 1
- The first line does not specify that the expression inherits the first line, namely bit1, mask1 = 1<<1, 1<< 1-1, so bit1 == 2, mask1 == 1;
- Line 2 does not define constants
- Line 3 does not specify that the expression inherits from the first line, namely bit3, mask3 = 1<<3, 1<< 3-1, so bit0 == 8, mask0 == 7;
The principle of
Each line in the const block is described in Go using the spec data structure, which is declared as follows:
ValueSpec struct {
Doc *CommentGroup // associated documentation; or nil
Names []*Ident // value names (len(Names) > 0)
Type Expr // value type; or nil
Values []Expr // initial values; or nil
Comment *CommentGroup // line comments; or nil
}
Copy the code
This section contains the constants defined in a row. If N constants are defined in a row, the length of the ValueSpec.Names section is N.
A const block is actually a slice of type spec that represents multiple lines within a const.
The pseudo-algorithm for constructing constants during compilation is as follows:
for iota, spec := range ValueSpecs {
for i, name := range spec.Names {
obj := NewConst(name, iota...).// IoTA is passed in here to construct constants. }}Copy the code
You can see that IOTA is actually an index that traverses a const block and does not increment even if ioTA is used multiple times in each row.