乍一看,当您需要一个不希望为负数的 int 时,似乎人们可能会选择 uint 。然而,在实践中似乎 int 几乎总是首选。
我看到的一般建议如下:
我还注意到 Go 会让你将负 int 转换为 uint 并给出一些奇怪的结果:
x := -5
y := uint(x)
fmt.Println(y)
>> 18446744073709551611
Run Code Online (Sandbox Code Playgroud)
所以,我的理解是,在处理整数时我应该始终使用 int,无论符号如何,除非我发现自己需要 uint,并且在这种情况下我会知道(我认为???)。
我的问题:
另外,我问的是 Go 的具体实现。
这个答案是针对 C 的,但它在这里是相关的。
一般来说,如果您使用整数,您应该只使用
int类型。
通常建议这样做,因为我们“通常”遇到的大多数代码都处理 type int。通常也不需要您在使用 anint和 a uinttype 之间进行选择。
不要使用无符号类型来强制或建议数字必须为正数。那不是他们的目的。
这是相当主观的。您可以很好地使用它来保持程序和数据类型安全,并且不必费心处理由于负整数的情况而偶尔出现的错误。
“这是 Go 编程语言所推荐的,当您想要进行按位运算时,uint 的具体示例非常有用”
这看起来很模糊。请添加此内容的来源,我想阅读它。
Run Code Online (Sandbox Code Playgroud)x := -5 y := uint(x) fmt.Println(y) >> 18446744073709551611
这是许多语言的典型特征。这背后的逻辑是,当您将int类型转换为 a时uint,用于 a 的二进制表示形式int会被推入该uint类型中。最终,一切都只是二进制的抽象。例如,看一下这段代码及其输出:
a := int64(-123)
byteSliceRev := *(*[8]byte)(unsafe.Pointer(&a)) // The byte slice representation we get is LTR in increasing order of significance
u := uint(a)
byteSliceRevU := *(*[8]byte)(unsafe.Pointer(&u))
byteSlice, byteSliceU := make([]byte, 8), make([]byte, 8)
for i := 0; i < 8; i++ {
byteSlice[i], byteSliceU[i] = byteSliceRev[7-i], byteSliceRevU[7-i]
}
fmt.Println(u)
// 18446744073709551493
fmt.Printf("%b\n", byteSlice)
// [11111111 11111111 11111111 11111111 11111111 11111111 11111111 10000101]
fmt.Printf("%b\n", byteSliceU)
// [11111111 11111111 11111111 11111111 11111111 11111111 11111111 10000101]
Run Code Online (Sandbox Code Playgroud)
-5int64类型的字节表示与18446744073709551493类型的字节表示相同。uint
所以,我的理解是,在处理整数时我应该始终使用 int,无论符号如何,除非我发现自己需要 uint,并且在这种情况下我会知道(我认为???)。
但这对于“我们”编写的每一个代码来说不都是或多或少的吗?!
这是正确的外卖吗?如果是这样,为什么会这样呢?
我希望我已经回答了这两个问题。如果您还有任何疑问,请随时问我。
什么时候应该使用 uint 的例子是什么?-- 也许是一个具体的例子,而不是“进行二进制操作时”,因为我不确定我知道这意味着什么:)
想象这样一个场景,您的数据库中有一个表,其中有很多条目,其中的整数为id,该整数始终为正数。如果您将此数据存储为int每个条目的一位,实际上是无用的,并且当您缩放此数据时,您会丢失大量空间,而您本来可以使用uint并保存它。在传输数据时可以考虑类似的场景,准确地说是传输大量整数。此外,uint由于额外的位,正整数的范围是其对应的有符号整数的两倍,因此需要更长的时间才能用完数字。现在存储很便宜,所以人们通常会忽略这个所谓的微小收益。
另一个用例是类型安全。Auint永远不能为负数,因此如果代码的一部分对负数很敏感,那么它会非常方便。最好在浪费资源在数据上之前发现错误,只是为了发现它是不允许的,因为它是负数。
Package Image 使用 uint 等 crypto/tls,因此当您使用这些包时必须使用 uint。
一开始我会逻辑地使用它,但我不会为此争论,如果它成为一个问题,我会使用实用的方法。