Golang中如何使用Iota
这篇文章给大家介绍Golang中如何使用 Iota,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
创新互联主要从事成都网站设计、成都网站建设、外贸网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务广阳,10余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
如何实现枚举
iota 是 Go 中预声明的一个特殊常量。它会被预声明为0,但是它的值在编译阶段并非是固定的,当预声明的 iota 出现在一个常量声明中,它的值在第n个常量描述中的值为n(从0开始)。
比如,大家都或多或少了解电商系统。其中的订单模块一定会涉及到订单状态的流转。那么这时候,我们一般可以这样定义:
package main import "fmt" type OrderStatus int const ( 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 }
当然,这样看着好麻烦。其实,其他常量可以重复上一行 iota 表达式,我们可以改成这样。
package main import "fmt" type OrderStatus int const ( Cancelled OrderStatus = iota //订单已取消 0 NoPay //未支付 1 PendIng // 未发货 2 Delivered // 已发货 3 Received // 已收货 4 ) func main() { fmt.Println(Cancelled, NoPay) // 打印:0,1 }
有人会用 0 的值来表示状态吗?一般都不会,我们想以1开头,那么可以这样。
package main import "fmt" type OrderStatus int const ( Cancelled OrderStatus = iota+1 //订单已取消 1 NoPay //未支付 2 PendIng // 未发货 3 Delivered // 已发货 4 Received // 已收货 5 ) func main() { fmt.Println(Cancelled, NoPay) // 打印:1,2 }
我们还想在 Delivered 后跳过一个数字,才是 Received 的值,也就是 Received=6,那么可以借助 _ 符号。
package main import "fmt" type OrderStatus int const ( Cancelled OrderStatus = iota+1 //订单已取消 1 NoPay //未支付 2 PendIng // 未发货 3 Delivered // 已发货 4 _ Received // 已收货 6 ) func main() { fmt.Println(Received) // 打印:6 }
顺着来可以,倒着当然也行。
package main import "fmt" type OrderStatus int const ( Max = 5 ) const ( Received OrderStatus = Max - iota // 已收货 5 Delivered // 已发货 4 PendIng // 未发货 3 NoPay //未支付 2 Cancelled //订单已取消 1 ) func main() { fmt.Println(Received,Delivered) // 打印:5,4 }
还可以使用位运算,比如在 go 源码中的包 sync 中的锁上面有这么一段定义代码。
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 }
也许有人平常是直接定义常量值或者用字符串来表示的。
比如,上面这些我完全可以用 string 来表示,我还真见过用字符串来表示订单状态的。
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]) }
或者直接定义整形常量值。
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]) }
其实上述两种都可以,但是相比之下使用 iota 更有优势。
能保证一组常量的唯一性,人工定义的不能保证。
可以为一组动作分享同一种行为。
避免无效值。
提高代码阅读性以及维护。
延伸
按照上面我们所演示的,最后我们可以这样操作。
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 }
关于Golang中如何使用 Iota就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
文章名称:Golang中如何使用Iota
浏览路径:http://pwwzsj.com/article/pepios.html