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。