Tony Bai · Go 语言第一课
Tony Bai
资深架构师,tonybai.com 博主
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 59 讲
开篇词 (1讲)
结束语 (1讲)
Tony Bai · Go 语言第一课
15
15
1.0x
00:00/00:00
登录|注册

14|常量:Go在“常量”设计上的创新有哪些?

是否存在一些场合,使用显式字面值更为适合
灵活且简便的维护
引入iota行偏移量指示器
自动重复上一行
使用const代码块定义的常量集合
简化代码编写
由编译器保证安全性
自动转换为求值上下文中所需要的类型
无需显式类型转换
可直接参与表达式求值
拥有灵活性
布尔类型
字符串类型
数值类型
提供类型安全的保证
避免使用宏定义常量
编译器进行编译优化
减少运行时工作
值在整个程序生命周期内保持不变
在源码编译期间创建
思考题
实现枚举
隐式转型
无类型常量
常量的类型
Go语言常量的好处
常量的定义
常量

该思维导图由 AI 生成,仅供参考

你好,我是 Tony Bai。
在前面几节课中,我们学习了变量以及 Go 原生支持的基本数据类型,包括数值类型与字符串类型。这两类基本数据类型不仅仅可以被用来声明变量、明确变量绑定的内存块边界,还可以被用来定义另外一大类语法元素:常量
你可能会问:常量有什么好讲的呢?常量不就是在程序生命周期内不会改变的值吗?如果是其他主流语言的常量,可讲的确实不多,但 Go 在常量的设计上是有一些“创新”的。都有哪些创新呢?我们不妨先来剧透一下。Go 语言在常量方面的创新包括下面这几点:
支持无类型常量;
支持隐式自动转型;
可用于实现枚举。
这些创新的具体内容是什么呢?怎么来理解 Go 常量的这些创新呢?你可以先思考一下,接下来我们再来详细分析。
不过在讲解这些“创新”之前,我们还是要从 Go 常量的一些基本概念说起,这会有助于我们对 Go 常量有一个更为深入的理解。

常量以及 Go 原生支持常量的好处

Go 语言的常量是一种在源码编译期间被创建的语法元素。这是在说这个元素的值可以像变量那样被初始化,但它的初始化表达式必须是在编译期间可以求出值来的。
而且,Go 常量一旦声明并被初始化后,它的值在整个程序的生命周期内便保持不变。这样,我们在并发设计时就不用考虑常量访问的同步,并且被创建并初始化后的常量还可以作为其他常量的初始表达式的一部分。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go语言常量设计的创新和枚举实现方法是本文的重点。Go语言在常量设计上的创新包括支持无类型常量、隐式自动转型和可用于实现枚举。常量在Go语言中是在源码编译期间被创建的语法元素,其值在整个程序生命周期内保持不变,不需要考虑同步访问。相比于C语言,Go语言的常量设计消除了宏定义常量和const修饰的“只读变量”带来的问题,使得常量是类型安全的,对编译器优化友好。其中,无类型常量是一种常用的惯用法,它具有默认类型,但在表达式中可以隐式转型,使得在处理表达式混合数据类型运算时具有灵活性。此外,常量还可用于实现枚举,为代码编写带来一定程度的简化。Go语言的常量设计创新使得常量在语言中的应用更加灵活和便捷。文章还介绍了Go语言中使用const代码块定义的常量集合来实现枚举的方法,以及通过iota实现枚举常量的自动赋值和灵活性,使得维护枚举常量列表变得更加容易。通过对Go语言常量设计的创新和枚举实现的介绍,读者可以更好地理解和应用Go语言中的常量和枚举特性。文章内容涵盖了常量的编译期计算、类型安全、无类型常量的灵活性以及枚举实现的便捷性,为读者提供了全面的技术知识和应用指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Tony Bai · Go 语言第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(33)

  • 最新
  • 精选
  • 火夫
    个人觉得iota在一些场景下是方便一些,但更关键的在于代码可读性要好。像标准库syscall下有大量定义的常量,如果使用iota会看得头晕,心智负担太大。

    作者回复: 没错,也有一些场合不适于使用iota。你提到的syscall场合算是一个。因为系统调用的编号以及错误码值几乎形成了标准,直接用原值更好,也方便查找。

    2021-11-12
    2
    32
  • ivhong
    老师您好,我有个疑惑,望老师有时间帮忙解答一下。 go在普通类型变量计算时有意的取掉了隐式类型转换,而在常量计算时又有意的加上隐式类型转换,为什么要“特意”的区别设计呢?

    作者回复: 好问题!我的理解是:变量避免隐式转换是消除类型不安全的问题。而常量本身是不可改变的,不存在安全问题,untyped常量的“隐式”可以理解为一种“语法糖”。

    2022-03-07
    23
  • 多选参数
    有人老觉得 iota 没用,或者用的不多,但是在我看来,那可能是拿 Go 来实现了别的语言也可实现的一套,我觉得选择一门语言,更多是选择这门语言拥有的一些新特性,然后使用这些新特性。

    作者回复: 没错,要学习一门语言,最终目的就是学会用这门语言的思维去写这门语言的代码。go coding in go way. 而不为go coding in c way, or java way.

    2021-11-21
    4
    11
  • lesserror
    Tony Bai 老师的每篇文章都很精彩。以下困惑,麻烦有空解答一下: 1. 文中说:“但由于转型的对象是一个常量,所以这并不会引发类型安全问题,Go 编译器会保证这一转型的安全性。” 我理解的是Go编译器在编译阶段就能发现类型错误的问题,也就从而保证了类型转换的安全性吧。因为常量的类型的确定和运算都是在编译期间完成的。老师想表达的是这个意思吗? 2. 对于:iota怎么读比较准确呢?例如做技术分享的时候,直接每个字母分开来读的吗? 3. 1 << 2 等于 4 这种位运算 老师考虑在本课程中讲解吗?

    作者回复: 1. 差不多 2. iota的确是一个单词,表示“极微小”的意思。标准读音是 [aɪ'oʊtə] . 不过你也知道,很多程序员界的术语都读乱了,就像nginx这个词读啥的都有。 3. 篇幅有限,位运算没列入专题讲解。

    2021-11-13
    7
    6
  • mikewoo
    老师,请教一个问题,文中提到c语言借助宏定义字面值的形式作为常量类型,是在预编译阶段处理的,但是具有不安全性,请问这个不安全性怎么理解呢

    作者回复: 这里指类型安全。 提到类型安全,我们需要先说一下什么是类型安全。类型安全是一个计算机科学中的概念,主要指编程语言阻止或防止类型错误的程度水平。比如将一个字符串类型变量传递给一个接受int类型参数的函数时,语言编译器是否能检测出问题。 如果你学过C语言,你就知道宏是在预处理阶段仅仅是做的字符串替换。也就是说宏定义的所谓常量就是一个“字符串”,没有携带任何类型信息,即便对一个函数原型为int Foo(int num)的函数进行如下调用: #define NUM "5" void Foo(int num) { printf("num = %d\n", num); } int main() { Foo(NUM); } 调用中的NUM在预处理阶段被替换为"5",但预处理过程也不会有任何报错,因为预处理阶段没有“类型”的概念。 这样问题就被漏到了编译期间。编译器是否能捕捉到这个问题?不一定。在我的gcc上会给出warning。 $gcc testmacro.c testmacro.c:12:7: warning: incompatible pointer to integer conversion passing 'char [2]' to parameter of type 'int' [-Wint-conversion] Foo(NUM); ^~~ testmacro.c:5:15: note: expanded from macro 'NUM' #define NUM "5" ^~~ testmacro.c:7:14: note: passing argument to parameter 'num' here void Foo(int num) { ^ 1 warning generated. 但是如果程序员忽略warning,这部分错误就会留到 程序运行期间。 运行这个例子: $a.out num = 62984116

    2022-04-21
    2
    5
  • 功夫熊猫
    当你定义的值是一些固定值,比如端口或者进城的时候。或者就是那个数特别大

    作者回复: good。

    2021-11-13
    4
  • Geek_b6da5d
    颜色rgba,各种size等,都需要显式字面值

    作者回复: 可以的。

    2021-11-12
    4
  • 冯仁彬
    枚举经常会用到负数,go中怎么定义呢

    作者回复: go没有enum类型,可以用int型常量来模拟,可结合iota。

    2022-09-10归属地:辽宁
    3
  • zzy
    那go中是否支持复杂枚举呢,类似java中的,比如枚举中每个个体有name,code等

    作者回复: go语法连枚举类型都不支持,只是用常量“间接实现”了枚举值。你说的复杂枚举就更不支持了。

    2022-07-12
    3
  • mikewoo
    通过这节课的学习,我对go语言常量有了更深入的认识,尤其是文中对iota的讲解,解决了我很多困惑。

    作者回复: 👍

    2022-04-21
    3
收起评论
显示
设置
留言
33
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部