14|常量:Go在“常量”设计上的创新有哪些?
该思维导图由 AI 生成,仅供参考
常量以及 Go 原生支持常量的好处
- 深入了解
- 翻译
- 解释
- 总结
Go语言常量设计的创新和枚举实现方法是本文的重点。Go语言在常量设计上的创新包括支持无类型常量、隐式自动转型和可用于实现枚举。常量在Go语言中是在源码编译期间被创建的语法元素,其值在整个程序生命周期内保持不变,不需要考虑同步访问。相比于C语言,Go语言的常量设计消除了宏定义常量和const修饰的“只读变量”带来的问题,使得常量是类型安全的,对编译器优化友好。其中,无类型常量是一种常用的惯用法,它具有默认类型,但在表达式中可以隐式转型,使得在处理表达式混合数据类型运算时具有灵活性。此外,常量还可用于实现枚举,为代码编写带来一定程度的简化。Go语言的常量设计创新使得常量在语言中的应用更加灵活和便捷。文章还介绍了Go语言中使用const代码块定义的常量集合来实现枚举的方法,以及通过iota实现枚举常量的自动赋值和灵活性,使得维护枚举常量列表变得更加容易。通过对Go语言常量设计的创新和枚举实现的介绍,读者可以更好地理解和应用Go语言中的常量和枚举特性。文章内容涵盖了常量的编译期计算、类型安全、无类型常量的灵活性以及枚举实现的便捷性,为读者提供了全面的技术知识和应用指导。
《Tony Bai · Go 语言第一课》,新⼈⾸单¥59
全部留言(33)
- 最新
- 精选
- 火夫个人觉得iota在一些场景下是方便一些,但更关键的在于代码可读性要好。像标准库syscall下有大量定义的常量,如果使用iota会看得头晕,心智负担太大。
作者回复: 没错,也有一些场合不适于使用iota。你提到的syscall场合算是一个。因为系统调用的编号以及错误码值几乎形成了标准,直接用原值更好,也方便查找。
2021-11-12232 - ivhong老师您好,我有个疑惑,望老师有时间帮忙解答一下。 go在普通类型变量计算时有意的取掉了隐式类型转换,而在常量计算时又有意的加上隐式类型转换,为什么要“特意”的区别设计呢?
作者回复: 好问题!我的理解是:变量避免隐式转换是消除类型不安全的问题。而常量本身是不可改变的,不存在安全问题,untyped常量的“隐式”可以理解为一种“语法糖”。
2022-03-0723 - 多选参数有人老觉得 iota 没用,或者用的不多,但是在我看来,那可能是拿 Go 来实现了别的语言也可实现的一套,我觉得选择一门语言,更多是选择这门语言拥有的一些新特性,然后使用这些新特性。
作者回复: 没错,要学习一门语言,最终目的就是学会用这门语言的思维去写这门语言的代码。go coding in go way. 而不为go coding in c way, or java way.
2021-11-21411 - lesserrorTony Bai 老师的每篇文章都很精彩。以下困惑,麻烦有空解答一下: 1. 文中说:“但由于转型的对象是一个常量,所以这并不会引发类型安全问题,Go 编译器会保证这一转型的安全性。” 我理解的是Go编译器在编译阶段就能发现类型错误的问题,也就从而保证了类型转换的安全性吧。因为常量的类型的确定和运算都是在编译期间完成的。老师想表达的是这个意思吗? 2. 对于:iota怎么读比较准确呢?例如做技术分享的时候,直接每个字母分开来读的吗? 3. 1 << 2 等于 4 这种位运算 老师考虑在本课程中讲解吗?
作者回复: 1. 差不多 2. iota的确是一个单词,表示“极微小”的意思。标准读音是 [aɪ'oʊtə] . 不过你也知道,很多程序员界的术语都读乱了,就像nginx这个词读啥的都有。 3. 篇幅有限,位运算没列入专题讲解。
2021-11-1376 - 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-2125 - 功夫熊猫当你定义的值是一些固定值,比如端口或者进城的时候。或者就是那个数特别大
作者回复: good。
2021-11-134 - Geek_b6da5d颜色rgba,各种size等,都需要显式字面值
作者回复: 可以的。
2021-11-124 - 冯仁彬枚举经常会用到负数,go中怎么定义呢
作者回复: go没有enum类型,可以用int型常量来模拟,可结合iota。
2022-09-10归属地:辽宁3 - zzy那go中是否支持复杂枚举呢,类似java中的,比如枚举中每个个体有name,code等
作者回复: go语法连枚举类型都不支持,只是用常量“间接实现”了枚举值。你说的复杂枚举就更不支持了。
2022-07-123 - mikewoo通过这节课的学习,我对go语言常量有了更深入的认识,尤其是文中对iota的讲解,解决了我很多困惑。
作者回复: 👍
2022-04-213