【FAQ】go的十万个为什么?-值|Go主题月

168 阅读4分钟

本文中译于官方FAQ

原文地址:golang.org/doc/faq#val…

Go项目的value值

为什么Go不提供隐式数值转换?

C语言中的数字类型之间自动转换的便利性被它引起的混乱所笼罩。表达式什么时候是无符号的?价值多少?它会溢出吗?结果是否可移植,独立于执行它的机器?这也使编译器复杂化。“通常的算术转换”不容易实现,并且在整个体系结构中不一致。出于可移植性的原因,我们决定以代码中的一些显式转换为代价,使事情变得清晰明了。但是,Go中的常量定义(没有符号和大小注释的任意精度值)大大改善了问题。

一个相关的细节是,与C语言 不同,即使int是64位类型,intint64是不同的类型。在Go中int类型是通用的;如果您关心整数可以容纳多少位,那么Go鼓励您保持明确。

常量在Go中如何工作?

尽管Go严格要求在不同数值类型的变量之间进行转换,但语言中的常量要灵活得多。诸如23、3.14159和math.Pi之类的文字常量占据一种理想的数字空间,具有任意精度,并且没有上溢或下溢。例如,math.Pi在源代码中将的值指定为63个位置,并且涉及该值的常量表达式保持的精度超出了float64所能容纳的范围。只有将常量或常量表达式分配给变量时(程序中的存储位置),它才会成为具有常规浮点属性和精度的“计算机”数字。

另外,由于它们只是数字,而不是类型化的值,因此Go中的常量比变量可以更自由地使用,从而减轻了严格转换规则周围的一些尴尬。一个人可以写这样的表达式:

sqrt2 := math.Sqrt(2)

编译器没有报错,因为理想的2可以安全,准确地转换为float64以调用math.Sqrt

标题为“ Constants ”的博客文章 更详细地探讨了该主题。

为什么内置Map?

同样的原因是:字符串是如此强大而重要的数据结构,以至于在语法支持下提供了一种出色的实现,使编程变得更加愉快。我们认为Go的Map实施能力足够强大,可以用于绝大多数用途。如果一个特定的应用程序可以从定制实现中受益,则可以编写一个应用程序,但是在语法上不那么方便。这似乎是一个合理的权衡。

为什么Map不能用切片作为Key?

映射查找需要等式运算符,切片没有实现这个。他们没有实现是因为在这些类型上没有很好地定义平等。有多种考虑因素,包括浅层比较与深层比较,指针与值比较,如何处理递归类型等等。我们可能会重新讨论这个问题-并且对slice实现等式运算不会使任何现有程序无效-但在没有清楚知道slice平等意味着什么的情况下,暂时将其忽略会更简单。

在Go 1中,与以前的版本不同,为结构和数组定义了等式运算,因此可以将此类用作映射键。不过,切片仍然没有等式定义。

为什么Map,Slice,Channel是引用,而数组是值?

关于这个话题有很多历史。早期,Map和Channel在语法上是指针,因此无法声明或使用非指针实例。此外,我们在数组应如何工作方面也遇到了困难。最终,我们决定严格区分指针和值,使该语言更难使用。更改这些类型以用作对关联的共享数据结构的引用解决了这些问题。这项更改使该语言增加了一些令人遗憾的复杂性,但对可用性产生了很大影响:Go引入时成为一种更具生产力和舒适性的语言。