文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

iota在Go中的使用方法

2023-06-14 22:39

关注

这篇文章将为大家详细讲解有关iota在Go中的使用方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

go是什么

golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以直接部署到目标机器而无需额外的依赖,所以golang的性能优于其他的解释性语言,且可以在golang中使用goroutine来实现并发性,它提供了一个非常优雅的goroutine调度程序系统,可以很容易地生成数百万个goroutine。

介绍

Go 语言实际上没有直接支持枚举的关键字。一般我们都是通过 const + iota 实现枚举的能力。

有人要问了,为什么一定要使用枚举呢?stackoverflow 上有一个高赞的回答,如下:

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.

简单翻译一下, 两点很重要。

如何实现枚举

iota 是 Go 中预声明的一个特殊常量。它会被预声明为0,但是它的值在编译阶段并非是固定的,当预声明的 iota 出现在一个常量声明中的时候,它的值在第n个常量描述中的值为n(从0开始)。所以它只在同类型多个常量声明的情况下才显得有意义。

比如,大家都了解的电商,订单系统一定会涉及到订单状态的流转。那么这时候,我们一般可以这样做:

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}

当然,这样看着好麻烦。其实,其他常量可以重复上一行 iota 表达式,我们可以改成这样。

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}

有人会用 0 的值来表示状态吗?一般都不会,我们想以1开头,那么可以这样。

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}

我们还想在 Delivered 后跳过一个数字,才是 Received 的值,也就是 Received=6,那么可以借助 _ 符号。

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}

顺着来可以,倒着当然也行。

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}

你还可以使用位运算,比如在 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 mainimport "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 mainimport "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 mainimport ( "fmt")type OrderStatus intconst (  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}

关于“iota在Go中的使用方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯