Go Rune
最后修改时间 2024 年 4 月 11 日
在本文中,我们将展示如何在 Golang 中使用 rune。
Rune 是 int32
数据类型的一个别名。它表示一个 Unicode 码点。Unicode 码点或码位是一个数值,通常用于表示 Unicode 字符。int32
的大小足以表示当前 140,000 个 Unicode 字符的容量。
ASCII 定义了 128 个字符,由码点 0-127 标识。Unicode 是 ASCII 的超集,它定义了 1,114,112 个码点的编码空间。
最初的 rune 这个词属于各种古代日耳曼民族的书面语言,特别是斯堪的纳维亚人和盎格鲁-撒克逊人。
字符串是字节序列;更确切地说,是任意字节的切片。在 Go 中,源代码是 UTF8。字符串可以包含以 UTF-8 编码的 Unicode 文本,它使用一到四个字节来编码所有 Unicode 码点。
Go Rune 常量
Go rune 常量由一对单引号 '
分隔。
package main import ( "fmt" "reflect" ) func main() { a1 := '🦍' var a2 = 'k' var a3 rune = '🦡' fmt.Printf("%c - %s\n", a1, reflect.TypeOf(a1)) fmt.Printf("%c - %s\n", a2, reflect.TypeOf(a2)) fmt.Printf("%c - %s\n", a3, reflect.TypeOf(a3)) }
我们定义了三个 rune 常量。
a1 := '🦍' var a2 = 'k' var a3 rune = '🦡'
我们有两个 emoji 和一个 ASCII 字符。如果未显式指定,Go 会自动推断 rune
类型。
fmt.Printf("%c - %s\n", a1, reflect.TypeOf(a1)) fmt.Printf("%c - %s\n", a2, reflect.TypeOf(a2)) fmt.Printf("%c - %s\n", a3, reflect.TypeOf(a3))
我们打印字符及其类型。
$ go run rune_constant.go 🦍 - int32 k - int32 🦡 - int32
我们可以使用转义字符来定义 rune 常量。
package main import ( "fmt" ) func main() { a1 := '🧺' a2 := '\u2665' a3 := '\U0001F3A8' fmt.Printf("%c\n", a1) fmt.Printf("%c\n", a2) fmt.Printf("%c\n", a3) }
我们定义了三个常量;其中两个使用了转义字符。
a2 := '\u2665'
在第一种情况下,\u
后面跟着正好四个十六进制数字。
a3 := '\U0001F3A8'
在第二种情况下,\U
后面跟着正好八个十六进制数字。
$ go run rune_escapes.go 🧺 ♥ 🎨
Go Rune Unicode 码点
Unicode 码点指的是 Unicode 表中的字符。
package main import "fmt" func main() { s1 := "falcon" r1 := []rune(s1) fmt.Printf("%U\n", r1) s2 := "🐧🐧🐧" r2 := []rune(s2) fmt.Printf("%U\n", r2) }
使用 %U
格式动词,我们可以得到 Unicode 码点。
$ go run code_points.go [U+0066 U+0061 U+006C U+0063 U+006F U+006E] [U+1F427 U+1F427 U+1F427]
Go 计算 Rune 数量
在下面的示例中,我们计算字符串中 rune 的数量。
package main import ( "fmt" "unicode/utf8" ) func main() { msg := "one 🐜" n1 := len(msg) n2 := utf8.RuneCountInString(msg) fmt.Println(n1) fmt.Println(n2) }
使用 len
函数,我们可以得到字节数。要计算 rune 的数量,我们使用 utf8.RuneCountInString
函数。
$ go run count.go 8 5
Go Rune 和字节
Go 中的字节是 uint8
的别名;它是一个“ASCII 字节”。
package main import ( "fmt" ) func main() { msg := "🐘 🦥 🐋" data := []rune(msg) fmt.Println(data) data2 := []byte(msg) fmt.Println(data2) }
我们有一个由三个 emoji 和两个空格组成的字符串。我们打印 rune 和字节的切片进行比较。
$ go run rune_bytes.go [128024 32 129445 32 128011] [240 159 144 152 32 240 159 166 165 32 240 159 144 139]
Go 遍历 Rune
for/range 形式会遍历 rune。
package main import ( "fmt" ) func main() { msg := "one 🐘 and three 🐋" for idx, e := range msg { fmt.Printf("Char:%s Byte pos: %d \n", string(e), idx) } }
该示例遍历 rune。它显示了字符及其在字符串中的字节位置。
$ go run loop.go Char:o Byte pos: 0 Char:n Byte pos: 1 Char:e Byte pos: 2 Char: Byte pos: 3 Char:🐘 Byte pos: 4 Char: Byte pos: 8 Char:a Byte pos: 9 Char:n Byte pos: 10 Char:d Byte pos: 11 Char: Byte pos: 12 Char:t Byte pos: 13 Char:h Byte pos: 14 Char:r Byte pos: 15 Char:e Byte pos: 16 Char:e Byte pos: 17 Char: Byte pos: 18 Char:🐋 Byte pos: 19
在下一个示例中,我们有另一种遍历 rune 的方法。
package main import ( "fmt" ) func main() { msg := "one 🐘 and three 🐋" data := []rune(msg) for i := 0; i < len(data); i++ { fmt.Printf("Char %c Unicode: %U, Rune pos: %d\n", data[i], data[i], i) } fmt.Println() }
我们将字符串转换为 rune 切片,然后使用 for 循环遍历该切片。
$ go run loop2.go Char o Unicode: U+006F, Rune pos: 0 Char n Unicode: U+006E, Rune pos: 1 Char e Unicode: U+0065, Rune pos: 2 Char Unicode: U+0020, Rune pos: 3 Char 🐘 Unicode: U+1F418, Rune pos: 4 Char Unicode: U+0020, Rune pos: 5 Char a Unicode: U+0061, Rune pos: 6 Char n Unicode: U+006E, Rune pos: 7 Char d Unicode: U+0064, Rune pos: 8 Char Unicode: U+0020, Rune pos: 9 Char t Unicode: U+0074, Rune pos: 10 Char h Unicode: U+0068, Rune pos: 11 Char r Unicode: U+0072, Rune pos: 12 Char e Unicode: U+0065, Rune pos: 13 Char e Unicode: U+0065, Rune pos: 14 Char Unicode: U+0020, Rune pos: 15 Char 🐋 Unicode: U+1F40B, Rune pos: 16
来源
在本文中,我们使用了 Go rune。