The following tutorial column from golang will introduce how to use iota in Go. I hope it will be helpful to friends who need it!
The Go language actually does not directly support the enumeration keyword. Generally, we implement enumeration capabilities through const
iota
.
Someone may ask, why must we use enumerations? There is a highly praised answer on stackoverflow
, as follows:
You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like type constants (contract status: “permanent”, “temp”, “apprentice”), or flags (“execute now”, “defer execution”). If you use enums instead of integers (or String codes), you increase compile-time checking and avoid errors from passing in invalid constants, and you document which values are legal to use. BTW, overuse of enums might mean that your methods do too much (it's often better to have several separate methods, rather than one method that takes several flags which modify what it does), but if you have to use flags or type codes, enums are the way to go.
Simple translation, two points Very important.
iota
is a special constant pre-declared in Go. It will be predeclared as 0, but its value is not fixed at the compilation stage. When the predeclared iota
appears in a constant declaration, its value is in the nth constant description. The value of is n (starting from 0). So it only makes sense if there are multiple constant declarations of the same type.
For example, as everyone knows about e-commerce, the order system will definitely involve the flow of order status. So at this time, we can generally do this:
package mainimport "fmt"type OrderStatus intconst ( Cancelled OrderStatus = iota //订单已取消 0 NoPay OrderStatus = iota //未支付 1 PendIng OrderStatus = iota // 未发货 2 Delivered OrderStatus = iota // 已发货 3 Received OrderStatus = iota // 已收货 4)func main() { fmt.Println(Cancelled, NoPay) // 打印:0,1}
Of course, this looks very troublesome. In fact, other constants can repeat the iota
expression in the previous line, and we can change it to this.
package mainimport "fmt"type OrderStatus intconst ( Cancelled OrderStatus = iota //订单已取消 0 NoPay //未支付 1 PendIng // 未发货 2 Delivered // 已发货 3 Received // 已收货 4)func main() { fmt.Println(Cancelled, NoPay) // 打印:0,1}
Does anyone use a value of 0 to represent status? Generally not, we want to start with 1, so that's fine.
package mainimport "fmt"type OrderStatus intconst ( Cancelled OrderStatus = iota+1 //订单已取消 1 NoPay //未支付 2 PendIng // 未发货 3 Delivered // 已发货 4 Received // 已收货 5)func main() { fmt.Println(Cancelled, NoPay) // 打印:1,2}
We also want to skip a number after Delivered
, which is the value of Received
, that is, Received=6
, then yes Use the _
symbol.
package mainimport "fmt"type OrderStatus intconst ( Cancelled OrderStatus = iota+1 //订单已取消 1 NoPay //未支付 2 PendIng // 未发货 3 Delivered // 已发货 4 _ Received // 已收货 6)func main() { fmt.Println(Received) // 打印:6}
You can do it along the way, and of course backwards.
package mainimport "fmt"type OrderStatus intconst ( Max = 5)const ( Received OrderStatus = Max - iota // 已收货 5 Delivered // 已发货 4 PendIng // 未发货 3 NoPay //未支付 2 Cancelled //订单已取消 1)func main() { fmt.Println(Received,Delivered) // 打印:5,4}
You can also use bit operations, for example, there is such a piece of code on the lock in the package sync
in the go source code.
const ( mutexLocked = 1 << iota //1<<0 mutexWoken //1<<1 mutexStarving //1<<2 mutexWaiterShift = iota //3 ) func main() { fmt.Println("mutexLocked的值",mutexLocked) //打印:1 fmt.Println("mutexWoken的值",mutexWoken) //打印:2 fmt.Println("mutexStarving的值",mutexStarving) //打印:4 fmt.Println("mutexWaiterShift的值",mutexWaiterShift) // 打印:3}
Maybe some people usually define constant values directly or use strings to represent them.
For example, I can use string
to represent the above. I have actually seen strings used to represent order status.
package main import "fmt" const ( Cancelled = "cancelled" NoPay = "noPay" PendIng = "pendIng" Delivered = "delivered" Received = "received") var OrderStatusMsg = map[string]string{ Cancelled: "订单已取消", NoPay: "未付款", PendIng: "未发货", Delivered: "已发货", Received: "已收货", } func main() { fmt.Println(OrderStatusMsg[Cancelled]) }
Or directly define the integer constant value.
package main import "fmt" const ( Cancelled = 1 NoPay = 2 PendIng = 3 Delivered = 4 Received = 5) var OrderStatusMsg = map[int]string{ Cancelled: "订单已取消", NoPay: "未付款", PendIng: "未发货", Delivered: "已发货", Received: "已收货", } func main() { fmt.Println(OrderStatusMsg[Cancelled]) }
In fact, both of the above are possible, but using iota
has more advantages.
According to what we demonstrated above, we can finally do this.
package main import ( "fmt") type OrderStatus int const ( Cancelled OrderStatus = iota + 1 //订单已取消 1 NoPay //未支付 2 PendIng // 未发货 3 Delivered // 已发货 4 Received // 已收货 5) //公共行为 赋予类型 String() 函数,方便打印值含义 func (order OrderStatus) String() string { return [...]string{"cancelled", "noPay", "pendIng", "delivered", "received"}[order-1] } //创建公共行为 赋予类型 int 函数 EnumIndex() func (order OrderStatus) EnumIndex() int { return int(order) } func main() { var order OrderStatus = Received fmt.Println(order.String()) // 打印:received fmt.Println(order.EnumIndex()) // 打印:5 }
This article mainly introduces the use of iota
in Golang
and why we should use it.
I don’t know what tricks you usually use for this kind of scene, please leave a message below to exchange.
The above is the detailed content of How to use iota in Go. For more information, please follow other related articles on the PHP Chinese website!