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
类型。