Go内置len()
function会返回已签名的int
。为什么不使用uint
?
len()
是否有可能返回负面内容?
据我所知,答案是否定的:
答案 0 :(得分:20)
len()
(和cap()
)返回int
,因为这是用于索引切片和数组(不是uint
)的内容。所以问题是更多"为什么Go在没有负指数时使用有符号整数来索引切片/数组?"。
答案很简单:计算索引很常见,如果在无符号整数中完成,这种计算往往容易下溢。像i := a-b+7
这样的无辜代码可能会为i == 4294967291
和a
的6和10的无辜值产生b
。这样的索引可能会溢出你的切片。大量的索引计算发生在0左右,并且使用无符号整数来纠正这些错误并且这些错误隐藏在数学上完全合理和合理的公式之后。这既不安全也不方便。
这是基于经验的权衡:对于使用无符号整数进行的索引计算,往往会发生下溢,而如果使用有符号整数进行索引计算,则溢出更不常见。
此外:在这些情况下使用无符号整数基本上没有任何好处。
答案 1 :(得分:5)
内置函数len和cap接受各种类型的参数 返回int类型的结果。实施保证了 结果总是适合int。
Golang是强类型语言,因此如果len()
为uint
,则代替:
i := 0 // int
if len(a) == i {
}
你应该写:
if len(a) == uint(i) {
}
或:
if int(len(a)) == i {
}
另见:
uint
32或64位
int
与uint
相同的大小uintptr
an unsigned integer large enough to store the uninterpreted bits of a pointer value
同样为了与C:CGo兼容,C.size_t
和C中数组的大小属于int
类型。
答案 2 :(得分:3)
有一个正在进行的提案“ issue 31795 Go 2: change len
, cap
to return untyped int if result is constant”
可能包含在Go 1.14(2010年第一季度)中
我们应该能够在
len
和cap
上做到这一点,而不会出现问题-实际上,stdlib中没有任何东西,因为通过修改后的类型检查器显示的类型进行了检查
将CL 179184视为PoC:这仍处于实验阶段。
截至noted below的peterSO,此事务已关闭。
正如您所指出的,使len始终为非类型的问题是结果的大小。
对于布尔值(以及字符串),无论哪种布尔值(或字符串),大小都是已知的。
我不确定这里的成本是否值得。今天有一条简单的规则:
len(x)
的类型为int
。
更改类型以取决于x
是什么,将以非正交的方式与各种代码更改交互。
例如,在建议的语义下,此代码编译:
const x string = "hello"
func f(uintptr)
...
f(len(x))
但是假设有人来了,并且希望能够修改
x
进行测试或类似的操作,所以他们s/const/var/
。
通常,这是相当安全的,但是现在f(len(x))
调用无法进行类型检查,并且它为什么能起作用,这将是一个神秘的事情。此更改似乎会添加比删除的粗糙边缘。
答案 3 :(得分:2)
长度是数组类型的一部分;它必须求值为可由类型
int
的值表示的非负常量。可以使用内置函数len
发现数组a的长度。元素可以通过整数索引0
到len(a)-1
来处理。数组类型总是一维的,但可以组合成多维类型。
我意识到说规范指示 X 可能有点循环,因为规范规定了 Y ,但由于长度不能超过{的最大值{1}} int
同样不可能返回len
- 独占值,因为它返回负值。