我最近正在阅读effective_go文档,在阅读"打印"部分时感到震惊:

版画

作为C程序员,%x int64(x)的预期输出也应该是ffffffffffffffff,所以上述输出对我来说是不合理的,有人可以告诉我为什么吗?


例如,Go在这里的行为不同于C。整数的%x动词表示使用十六进制(基数16)表示形式而不是其内存表示形式(将为2的补码)格式化数字的值。 %b用于二进制,%o用于八进制表示。

对于像-255这样的负数,其base16表示形式是-ff

Go对类型严格,您必须始终明确。如果您传递一个有符号整数,它将被格式化为一个有符号整数。如果要将其打印为无符号值,则必须像以下示例一样将其显式转换为无符号值:

输出(在Go Playground上尝试):

请注意,将带符号的值转换为其无符号版本(相同大小)时,它不会仅更改其类型的内存表示形式,因此转换后的值(无符号结果)将是带符号值的2的补码。

至于为什么这是负数的默认值,请阅读Rob Pike给出的理由:

Why is that not the default [the unsigned format]? Because if it were, there would be no way to print something as a negative number, which as you can see is a much shorter representation. Or to put it another way, %b %o %d %x all treat their arguments identically.

您可以在以下相关问题中看到如何/在何处实现此功能:Golang:二进制补码和fmt.Printf


The C Programming Language, Second Edition

x,X int ; unsigned hexadecimal number (without a leading 0x or 0X ),
using abcdef or ABCDEF for 10, ...,15.

x,X unsigned int ; unsigned hexadecimal notation (without a leading 0x
or 0X ), using abcdef for 0x or ABCDEF for 0X .

The GNU C Library Reference Manual, Version 2.27

‘%x’, ‘%X’ Print an integer as an unsigned hexadecimal number. ‘%x’
uses lower-case letters and ‘%X’ uses upper-case.

我很震惊-震惊-发现整数转换正在进行中!

在C语言中,隐式转换比比皆是。在Go中,根据设计,转换是显式的。

在C中,printf隐式将带符号整数转换为格式为%x的无符号整数。 Go fmt.Printf不会。

从设计上来说,Go不是C。Go确实与C有相似之处,这可能会困住粗心的人。


int64(math.MaxUint64)溢出int64的范围:

游乐场:https://play.golang.org/p/J6buiaaZcFt

参见https://golang.org/pkg/math/#pkg-constants和https://play.golang.org/p/iul2dgRbK2E