我是一些“内存分配器”类型代码,使用数组和索引而不是指针。我希望数组索引的大小小于指针。我很在意,因为我将“指针”作为整数索引存储在数组中,而不是 64 位指针。
我在 Go 规范中看不到任何说明数组索引的内容。显然它是某种整数。传递非常大的值会使运行时抱怨我不能传递负数,所以我猜测它以某种方式转换为有符号整数。那么它是一个int32
吗?我猜这不是int64
因为我没有触及最高位(这将是 2 对负数的恭维)。
我是一些“内存分配器”类型代码,使用数组和索引而不是指针。我希望数组索引的大小小于指针。我很在意,因为我将“指针”作为整数索引存储在数组中,而不是 64 位指针。
我在 Go 规范中看不到任何说明数组索引的内容。显然它是某种整数。传递非常大的值会使运行时抱怨我不能传递负数,所以我猜测它以某种方式转换为有符号整数。那么它是一个int32
吗?我猜这不是int64
因为我没有触及最高位(这将是 2 对负数的恭维)。
数组可以由任何整数类型索引。
长度是数组类型的一部分,并且必须是计算结果为非负整数值的常量表达式。
在索引表达式中,例如a[x]
:
x
必须是整数值并且0 <= x < len(a)
但是指数的大小是有限制的;长度和容量的描述说:
内置函数
len
并cap
接受各种类型的参数并返回 type 的结果int
。该实现保证结果始终适合int
.
因此,数组的声明大小或索引表达式中的索引可以是任何整数类型(大小相同或- 尽管它是不同的类型)。int
uint
uintptr
int8
int16
int32
int64
uint8
uint16
uint32
uint64
int
int32
int64
这确实是一个非常有趣的问题。我也没有在文档中找到任何直接规则;相反,我在群组中发现了两个很棒的讨论。
在第一个中,在很多事情中,我找到了一个答案,为什么索引被实现为int
- 但不是uint
:
算法可以受益于表达负偏移等的能力。如果索引未签名,那么在这些情况下您总是需要进行转换。
第二个int64
专门讨论了用于大型数组的可能性(但仅限于可能性!) ,提到了len
和功能的限制(文档cap
中实际上提到了这些限制):
内置函数 len 和 cap 接受各种类型的参数并返回 int 类型的结果。该实现保证结果始终适合 int。
不过,我确实同意,更……官方的观点不会受到伤害。)
数组和切片由int
s 索引。Anint
定义为 32 或 64 位有符号整数。最常见的实现 (6g) 使用 32 位整数,而不管此时的体系结构如何。但是,计划最终在 64 位机器上 int 将是 64 位,因此与指针的长度相同。
语言规范定义了 3 种依赖于实现的数字类型:
uint either 32 or 64 bits
int same size as uint
uintptr an unsigned integer large enough to store the uninterpreted bits of a pointer value