Golang Rune 类型
最后修改时间 2025 年 5 月 8 日
本教程讲解如何在 Go 中使用内置的 rune 类型。我们将通过实际的文本处理示例涵盖 Unicode 处理。
Go 中的 rune 类型是 int32 的别名,代表一个 Unicode 码点。它用于处理 UTF-8 编码字符串中的单个字符,UTF-8 是 Go 的默认字符串编码。
在 Go 中,rune 为国际字符提供了良好的支持。与字节不同,rune 可以表示 UTF-8 编码中需要多个字节的字符,例如非 ASCII 字符。
Rune 的基本声明和用法
使用 rune 的最简单方法是将它们声明为字符字面量。此示例演示了基本的 rune 操作和类型转换。
注意:在 Go 中,单引号用于 rune 字面量。
package main
import "fmt"
func main() {
// Declaring rune variables
var r1 rune = 'A'
r2 := '€' // Euro symbol
// Printing runes and their types
fmt.Printf("r1: %c, type: %T\n", r1, r1)
fmt.Printf("r2: %c, type: %T\n", r2, r2)
// Converting between rune and integer
codePoint := int(r2)
fmt.Printf("Euro code point: %d\n", codePoint)
// Converting back to rune
r3 := rune(codePoint)
fmt.Printf("Converted back: %c\n", r3)
}
该示例展示了 rune 的声明、使用格式动词进行打印以及 rune 和整数类型之间的转换。%c 格式动词显示字符。
使用 Rune 迭代字符串
Go 中的字符串是 UTF-8 编码的字节序列。使用 range 遍历字符串会遍历 rune,而不是字节。此示例演示了正确的字符串迭代。
package main
import "fmt"
func main() {
s := "Hello, 世界"
// Byte-by-byte iteration
fmt.Println("Byte iteration:")
for i := 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
fmt.Println()
// Rune-by-rune iteration
fmt.Println("Rune iteration:")
for idx, r := range s {
fmt.Printf("%d: %c (U+%04X)\n", idx, r, r)
}
// Counting runes
fmt.Printf("Length in bytes: %d\n", len(s))
fmt.Printf("Length in runes: %d\n", len([]rune(s)))
}
range 循环正确处理多字节 UTF-8 字符。字节迭代显示原始字节,而 rune 迭代显示正确的 Unicode 字符。
Rune 操纵和函数
unicode 包提供了用于 rune 分类和转换的函数。此示例演示了常见的 rune 操作。
package main
import (
"fmt"
"unicode"
)
func main() {
runes := []rune{'A', 'ä', '3', ' ', '世', '\t'}
for _, r := range runes {
fmt.Printf("Rune: %c\n", r)
fmt.Printf(" IsLetter: %t\n", unicode.IsLetter(r))
fmt.Printf(" IsDigit: %t\n", unicode.IsDigit(r))
fmt.Printf(" IsSpace: %t\n", unicode.IsSpace(r))
fmt.Printf(" Lowercase: %c\n", unicode.ToLower(r))
fmt.Printf(" Uppercase: %c\n", unicode.ToUpper(r))
fmt.Println()
}
}
unicode 包的函数使用 rune 来提供字符分类和大小写转换。这对于正确的文本处理至关重要。
从 Rune 构建字符串
Rune 可以转换为字符串,可以单独转换,也可以作为切片转换。此示例展示了从 rune 值构建字符串。
package main
import "fmt"
func main() {
// Single rune to string
r := '😊'
s1 := string(r)
fmt.Println("Smile:", s1)
// Rune slice to string
runes := []rune{'H', 'e', 'l', 'l', 'o', ' ', '世', '界'}
s2 := string(runes)
fmt.Println("Greeting:", s2)
// Modifying runes in a string
msg := []rune("Hello World")
msg[6] = 'G'
msg[7] = 'o'
msg[8] = 'l'
msg[9] = 'a'
msg[10] = 'ng'
fmt.Println("Modified:", string(msg))
}
在 Go 中,在 rune 切片和字符串之间进行转换非常高效。这使得通过处理 rune 切片可以轻松地进行字符串操作。
使用 Rune 处理无效 UTF-8
处理外部数据时,可能会出现无效的 UTF-8 序列。此示例演示了如何安全地处理这种情况。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// Contains invalid UTF-8 sequence
data := []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x80, 0x80, 0xef, 0xbc, 0xa5}
// Safe conversion with utf8.DecodeRune
for len(data) > 0 {
r, size := utf8.DecodeRune(data)
if r == utf8.RuneError {
fmt.Printf("Invalid UTF-8 sequence: %x\n", data[:size])
} else {
fmt.Printf("Valid rune: %c\n", r)
}
data = data[size:]
}
// Checking string validity
str := string(data)
if !utf8.ValidString(str) {
fmt.Println("String contains invalid UTF-8")
} else {
fmt.Println("String is valid UTF-8")
}
}
utf8 包提供了安全处理潜在无效 UTF-8 数据的函数。这对于健壮的文本处理应用程序至关重要。
来源
本教程通过 Unicode 文本处理和操作的实际示例,涵盖了 Go 中的 rune 类型。