为什么 fmt.Printf("%x", '?') ~> 16b5,而 fmt.Printf("%x", "?") ~> e19ab5?

use*_*610 3 utf-8 string-formatting go

package main\n\nimport (\n    "fmt"\n)\n\nfunc main() {\n    fmt.Printf("%c, %x, %x", \'\xe1\x9a\xb5\', \'\xe1\x9a\xb5\', "\xe1\x9a\xb5")\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
\xe1\x9a\xb5, 16b5, e19ab5\n
Run Code Online (Sandbox Code Playgroud)\n\n

https://play.golang.org/p/_Bs7JcdOfO

\n

use*_*610 5

因为每个人做的事情都不一样。两者都将参数格式化为十六进制数字,但各自对参数的看法不同。

\n\n

fmt.Printf("%x", \'\xe1\x9a\xb5\')以 32 位整数 (int32) 的形式打印单个 unicode 字符(符文,如果您愿意的话)。

\n\n

fmt.Printf("%x", "\xe1\x9a\xb5")将字符串(字符串的各个字节)打印为 8 位整数 (uint8)。当使用 utf-8 编码时,符文以三个字节进行编码。这就是为什么有六个十六进制数字(每个字节两个)的原因。

\n\n

要详细研究字符串的打印,请从fmtString文件中的函数开始fmt/print.go函数开始。

\n\n
func (p *pp) fmtString(v string, verb rune) {\n
Run Code Online (Sandbox Code Playgroud)\n

  • 您使用的语言有点令人困惑:用单引号打印 Unicode *代码点* (U+16B5)。代码点是由 unicode 联盟分配的数字以及该数字应代表的内容的描述。它“没有”说明应如何在文本文件中表示。使用双引号,它会打印 UTF-8 编码字符串中的原始字节。UTF-8 中的字节不直接按 8 位字节对齐,因此如果仅查看十六进制字符,则没有明显的对应关系。维基百科有一个关于其工​​作原理的[有用示例](https://en.wikipedia.org/wiki/UTF-8#Examples)。 (5认同)