大家好,我是建宇。今天分享给大家的一个提案,在Go社区已经讨论了9年(2013~2022),与我们日常编程息息相关。今天就让建宇和大家一起深入研究和理解提案《proposal: spec: allow constants of arbitrary data structure type》,看看有没有新的想法。背景我们来看下面的示例代码,如下:packagemainimport"fmt"funcmain(){vareach1=[]byte{'e','d','d','y'}consteach2=[]byte{'e','d','d','y'}fmt.Printf("each1是%q\n",each1)fmt.Printf("each2是%q\n",each2)}运行结果是什么,是正常输出,还是?最终运行结果如下:./prog.go:7:16:[]byte{…}(valueoftype[]byte)isnotconstant结果是Go编译失败,编译失败。原因是第7行(也就是const关键字那行)的常量定义有错误,无法将[]byte类型的值声明定义为常量。悟后也是一头雾水。Go的常量定义有类型限制。为什么?我希望我们可以结合另一个提案《proposal: Go 2: add const literals for reference types like structs, maps, and arrays》来看,它们都指向类似的诉求。目的是能够声明类似这样的东西:constkeys=[...]string{"friedfish","eddycjy",...}希望Go可以允许定义其他类型的常量,例如如:结构体(struct)、字典(map)和数组(array)等,不会产生编译错误,运行流畅。接受提案后,提案作者认为可以做到对原有Go代码无影响,不会有破坏性升级,代码可以得到有效简化。你觉得怎么样,还有什么可以期待的吗?不支持的原因Go核心团队的@RobertGriesemer表示:常量被有意设计为只支持原始类型(从Go的第一天就开始构想),不是语言缺陷,也不是设计缺陷,相信它们会影响其开场比想象的要深远。不知道常量的值类型支持有多开放,支持channel、slice、pointer类型?所以在不确定的情况下,在不知道有多少复杂性的情况下,官方试图让类型系统(包括常量是什么)保持相对简单。同时,现阶段这样做并没有明显的好处。如果要改的话,只可能是Go2会出现一些新的调整,而Go1不会。实景在评论区看到@ChangkunOu的留言,引用了“常量错误”的经典使用场景。代码如下:-constErrVerification=errors.New("crypto/rsa:verificationerror")+varErrVerification=errors.New("crypto/rsa:verificationerror")如果其中一个项目出现如下代码dependencies,那么它会破坏整个系统:import"cropto/rsa"funcinit(){rsa.ErrVerification=nil}这个在项目代码中很常见,最早的内部包想定义const常量报错,最后只能被迫对varflow做。在这些场景中,不确定你的值在哪里被改变了,你要检查很长时间。根本原因是Go的不可变变量部分缺少函数。小结在今天的文章中,我们介绍了Go中最常见的常量(const),它实际上只支持基本类型的定义。针对其不足之处,我们结合提案中的讨论和使用场景进行说明。相比之下,Go官方对于这个常量的类型支持非常谨慎。它认为好处并不明显,复杂性可能会增加。简单一点很好。你怎么认为?欢迎在评论区留言讨论。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的Why与设计思维Go语言进阶之旅:走得更远GoSourceCode阅读更多想添加箭头语法,这更像PHP!Go错误处理的新思路?使用左手函数和表达式
