乐趣区

关于后端:Go-常量只支持基本数据类型为什么社区撕了-9-年了

大家好,我是煎鱼。

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

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

背景

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

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》来看,指向的都是同类诉求。

目标是能申明相似:

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 官网对此常量的类型反对十分审慎,认为收益不明确、复杂度有可能增高,认为简略就好了。

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

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言能够看 Go 学习地图和路线,欢送 Star 催更。

Go 图书系列

  • Go 语言入门系列:初探 Go 我的项目实战
  • Go 语言编程之旅:深刻用 Go 做我的项目
  • Go 语言设计哲学:理解 Go 的为什么和设计思考
  • Go 语言进阶之旅:进一步深刻 Go 源码

更多浏览

  • Go 想要加个箭头语法,这下更像 PHP 了!
  • Go 错误处理新思路?用左侧函数和表达式
退出移动版