为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中,什么时候应该使用 uint 和 int?

在 Go 中,什么时候应该使用 uint 和 int?

Go
一只名叫tom的猫 2022-06-21 10:06:37
乍一看,当您需要一个不想成为负数的 int 时,似乎有人可能会选择 uint。然而,在实践中,似乎 int 几乎总是首选。我看到一般建议,例如:“一般来说,如果你使用整数,你应该只使用 int 类型。”“uint 通常只用于进行二元运算”“不要使用无符号类型来强制或建议数字必须是正数。这不是它们的用途。”“这是 Go 编程语言所推荐的,当你想要进行按位运算时,uint 的具体示例很有用”我还注意到 Go 会让你将负 int 转换为 uint 并给出一些奇怪的结果:  x := -5     y := uint(x)     fmt.Println(y)     >> 18446744073709551611所以,我的理解是,在处理整数时,我应该始终使用 int,而不管符号如何,除非我发现自己需要 uint,并且在这种情况下我会知道(我认为???)。我的问题:这是正确的外卖吗?如果是这样,为什么会这样?什么时候应该使用 uint 的例子是什么?- 也许是一个具体的例子,而不是“进行二进制操作时”,因为我不确定我知道这意味着什么:)另外,我问的是 Go 的具体实现。
查看完整描述

2 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

此答案适用于 C,但与此处相关。

通常,如果您使用整数,则应该只使用该int类型。

通常建议这样做,因为我们“通常”遇到的大多数代码都处理 type int。您通常也不需要在使用 anintuinttype 之间进行选择。

不要使用无符号类型来强制或建议数字必须为正数。那不是他们的目的。

这是相当主观的。您可以很好地使用它来保持您的程序和数据类型安全,并且不必为处理由于负整数情况而出现的偶然错误而烦恼。

“这是 Go 编程语言所推荐的,当你想要进行按位运算时,uint 的具体示例很有用”

这看起来很模糊。请为此添加来源,我想阅读它。

x := -5

y := uint(x)

fmt.Println(y)


>> 18446744073709551611

这是许多语言的典型特征。这背后的逻辑是,当您将int类型转换为 auint时,用于 的二进制表示会被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]

-5int64类型的字节表示与18446744073709551493类型相同。uint


所以,我的理解是,在处理整数时,我应该始终使用 int,而不管符号如何,除非我发现自己需要 uint,并且在这种情况下我会知道(我认为???)。


但这对于“我们”编写的每一个代码来说不是或多或少都是真的吗?!


这是正确的外卖吗?如果是这样,为什么会这样?


我希望我已经回答了这两个问题。如果您仍有任何疑问,请随时问我。


什么时候应该使用 uint 的例子是什么?- 也许是一个具体的例子,而不是“进行二进制操作时”,因为我不确定我知道这意味着什么:)


想象一个场景,您的数据库中有一个表,其中有很多条目,其中 an 的整数id始终为正数。如果您将此数据存储为int每个条目的一个位实际上是无用的,并且当您扩展它时,当您可以使用uint并保存它时,您将失去很多空间。在传输数据时可以考虑类似的情况,准确地说是传输大量整数。此外,uint由于额外的位,与对应的有符号整数相比,正整数的范围翻了一番,因此用完 numbers需要更长的时间。存储现在很便宜,所以人们通常会忽略这个所谓的小收益。


另一个用例是类型安全。Auint永远不会是负数,所以如果你的代码的一部分对负数很敏感,它可以证明是非常方便的。最好在将资源浪费在数据上之前得到错误,以发现它是不允许的,因为它是负面的。


查看完整回答
反对 回复 2022-06-21
?
月关宝盒

TA贡献1772条经验 获得超5个赞

Package Image 使用 uint 和 crypto/tls,所以当你使用这些包时你必须使用 uint。

我一开始是合乎逻辑地使用它,但我不会为此而争吵,如果它成为一个问题,我会使用一种实用的方法。

就像为什么将 int 用于 len()


查看完整回答
反对 回复 2022-06-21
  • 2 回答
  • 0 关注
  • 1024 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信