Golang中的字符串转换和Unicode

5

我正在阅读Go Essentials:

在Go中,字符串是一个不可变的字节序列(8位字节值),这与像Python、C#、Java或Swift这样的语言不同,这些语言的字符串是Unicode。

我正在尝试以下代码:

s := "日本語"
b :=[]byte{0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe8, 0xaa, 0x9e}
fmt.Println(string(b) == s) // true

for i, runeChar := range b {
    fmt.Printf("byte position %d: %#U\n", i, runeChar)
}

//byte position 0: U+00E6 'æ'
//byte position 1: U+0097
//byte position 2: U+00A5 '¥'
//byte position 3: U+00E6 'æ'
//byte position 4: U+009C
//byte position 5: U+00AC '¬'
//byte position 6: U+00E8 'è'
//byte position 7: U+00AA 'ª'
//byte position 8: U+009E

for i, runeChar := range string(b) {
    fmt.Printf("byte position %d: %#U\n", i, runeChar)
}

//byte position 0: U+65E5 '日'
//byte position 3: U+672C '本'
//byte position 6: U+8A9E '語'

问题:

  1. Golang在将字节数组转换为字符串进行编码时,从哪里获取Unicode?rune是如何形成的?Golang编译器是否会在编译过程中从文本文件编码中获取Unicode?

  2. 将String实现为像Java中的utf-16字符数组而不是像字节数组一样的utf-8字符数组有什么优缺点?


2
没有“类型转换”。Go语言默认字符串是一系列UTF-8编码的字节。 - JimB
1
问题1非常晦涩,您能澄清一下吗?问题2:Java错了。UTF-16是个愚蠢的编码方式:对于ASCII来说很浪费,同时仍然不能提供足够大的范围以处理所有的代码点。UTF-8才是唯一明智的编码方式。 - Volker
1个回答

10
您引用了一个弱势、不可靠的来源:Go Essentials: Strings。除此之外,其未提及Unicode码点或UTF-8编码等内容。
例如,
package main

import "fmt"

func main() {
    s := "日本語"
    fmt.Printf("Glyph:             %q\n", s)
    fmt.Printf("UTF-8:             [% x]\n", []byte(s))
    fmt.Printf("Unicode codepoint: %U\n", []rune(s))
}

操场:https://play.golang.org/p/iaYd80Ocitg

输出:

Glyph:             "日本語"
UTF-8:             [e6 97 a5 e6 9c ac e8 aa 9e]
Unicode codepoint: [U+65E5 U+672C U+8A9E]

参考资料:

Go博客: Go语言中的字符串、字节、符文和字符

Go编程语言规范

Unicode常见问题解答:UTF-8、UTF-16、UTF-32和BOM

Unicode联盟


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接