Go 常量只支持基本数据类型?为什么?社区撕了 9 年了...

大家好,我是煎鱼。

今天给大家分享的一个提案,已经在 Go 社区讨论了整整 9 年(2013~2022),它与我们的日常编程密切相关。

今天就由煎鱼和大家一起深入学习和了解提案《proposal: spec: allow constants of arbitrary data structure type[1]》吧,看看有没有什么新的想法。

背景

我们先看看以下示例代码,如下:

package main

import "fmt"

func main() {
 var each1 = []byte{'e', 'd', 'd', 'y'}
 const each2 = []byte{'e', 'd', 'd', 'y'}
 fmt.Printf("each1 is %q\n", each1)
 fmt.Printf("each2 is %q\n", each2)
}

运行结果是什么,是正常输出吗,还是?

最终运行结果如下:

./prog.go:7:16: []byte{…} (value of type []byte) is not constant

结果是 Go 编译失败,编译无法通过。

原因是第 7 行(也就是 const 关键字那行)的常量定义有错误,类型为 []byte 的值是不能作为常量来声明定义的。

悟了也雾了,Go 的常量定义有类型限制,为什么?

期望

我们结合另外个提案《proposal: Go 2: add const literals for reference types like structs, maps, and arrays[2]》来看,指向的都是同类诉求。

目的是能声明类似:

const keys = [...]string{"煎鱼", "eddycjy", ... }

期待 Go 能够允许定义其他类型的常量,例如:结构体(struct)、字典(map)和数组(array)等,不会再产生编译错误,顺利运行。

接受提案后,提案作者认为可以实现对原有的 Go 代码没有影响,不会存在破坏性升级,可以有效的简化代码等。

你觉得呢,还有没有别的更多的期望?

不支持的原因

Go 核心团队的 @Robert Griesemer 表示:常量是故意设计为只支持基本类型的(从 Go 第一天开始就被构思出来),不是语言的缺陷,也不是设计的缺陷,并认为将其开放的影响比想象中深远。

不知道要将常量的值类型支持要开放到什么程度,支撑到 channel、slice、指针类型?所以在不确定性下,不知道复杂度有多少,官方试图保持类型系统(包括常量是什么)的相对简单。

与此同时,做这件事现阶段还看不到明显的收益。如果要改,仅有可能在 Go2 发生一些新的调整,而不是 Go1。

真实场景

在评论区中看到欧神(@Changkun Ou)留言,举出了 ”常量错误“ 的经典使用场景。

代码如下:

- const ErrVerification = errors.New("crypto/rsa: verification error")
+ var ErrVerification = errors.New("crypto/rsa: verification error")

如果以下代码出现在项目依赖项之一中,则它会破坏整个系统:

import "cropto/rsa"
func init() {
 rsa.ErrVerification = nil
}

这是在项目代码中很常见的,最早内部包想定义 const 的常量错误,最后只能被迫 var 流操作一把。

在这些场景下,你的值在哪里被人改了,都不确定,还得查半天,根本原因是 Go 的不可变变量的功能部分缺失。

总结

在今天这篇文章中,我们介绍了 Go 中最常见的常量(const),实际上它仅支持基本类型的定义。而针对它的不足我们结合了提案中的讨论和使用场景进行了说明。

相较而言,Go 官方对此常量的类型支持非常谨慎,认为收益不明确、复杂度有可能增高,认为简单就好了。

你又怎么看呢?欢迎在评论区留言和讨论。

更多阅读

参考资料

[1]

proposal: spec: allow constants of arbitrary data structure type: https://github.com/golang/go/issues/6386

[2]

proposal: Go 2: add const literals for reference types like structs, maps, and arrays: https://github.com/golang/go/issues/21130

关注和加煎鱼微信,

获取一手业内消息和知识,拉你进交流群👇

4eeaa6831b3c886de9e1a6690426a6b8.jpeg

09438869a6bbbcdde6de2f79a6b10fda.png

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值