教程 > go 教程 > 阅读:1604

go 语言rune数据类型的详细介绍——迹忆客-ag捕鱼王app官网

在基础篇 go 语言字符串详解 一章中,我们介绍过在go语言中访问字符串的单个字符的方法。在列举的示例中有一个问题,就是如果一个字符占多个字节的话,例如:中文,在访问单个字符的时候就会出现问题。我们看下面的代码

package main
import (  
    "fmt"
)
func printbytes(s string) {  
    fmt.printf("bytes: ")
    for i := 0; i < len(s); i   {
        fmt.printf("%x ", s[i])
    }
}
func printchars(s string) {  
    fmt.printf("characters: ")
    for i := 0; i < len(s); i   {
        fmt.printf("%c ", s[i])
    }
}
func main() {  
    name := "hello world"
    fmt.printf("string: %s\n", name)
    printchars(name)
    fmt.printf("\n")
    printbytes(name)
    fmt.printf("\n\n")
    name = "迹忆客"
    fmt.printf("string: %s\n", name)
    printchars(name)
    fmt.printf("\n")
    printbytes(name)
}

上述代码执行结果如下

string: hello world
characters: h e l l o   w o r l d 
bytes: 48 65 6c 6c 6f 20 57 6f 72 6c 64 
string: 迹忆客
characters: è ¿ ¹ å ¿  å ® ¢ 
bytes: e8 bf b9 e5 bf 86 e5 ae a2

在上面程序中我们试图打印迹忆客的字符。但是出人意料的它打印出了è ¿ ¹ å ¿ å ® ¢ 。为什么会出现这种情况呢,原因就是utf-8 编码的中文它不是只占一个字节。因此我们试图打印字符,假设每个代码点都是一个字节长,这是错误的。

在 utf-8 编码中,一个代码点可以占用 1 个以上的字节。

那我们如何解决这个问题呢,那就需要用到 rune 这个万能钥匙了。


rune

rune 是go 中的内置类型,它是 int32 的别名。rune 代表 go 中的 unicode 代码点。代码点占用多少字节并不重要,可以用一个符文来表示。

下面让我们修改上面的代码

package main
import (
    "fmt"
)
func printbytes(s string) {
    fmt.printf("bytes: ")
    for i := 0; i < len(s); i   {
        fmt.printf("%x ", s[i])
    }
}
func printchars(s string) {
    fmt.printf("characters: ")
    runes := []rune(s)
    for i := 0; i < len(runes); i   {
        fmt.printf("%c ", runes[i])
    }
}
func main() {
    name := "hello world"
    fmt.printf("string: %s\n", name)
    printchars(name)
    fmt.printf("\n")
    printbytes(name)
    fmt.printf("\n\n")
    name = "迹忆客"
    fmt.printf("string: %s\n", name)
    printchars(name)
    fmt.printf("\n")
    printbytes(name)
    fmt.printf("\n")
}

这样上面的代码执行结果如下

string: hello world
characters: h e l l o   w o r l d 
bytes: 48 65 6c 6c 6f 20 57 6f 72 6c 64 
string: 迹忆客
characters: 迹 忆 客 
bytes: e8 bf b9 e5 bf 86 e5 ae a2 

上面代码中字符串被转换为一个符文切片。然后我们对它进行循环显示。可以看到,中文的字符已经被正常打印出来了。


使用 for range 循环迭代runes

上面的程序是迭代字符串的各个符文的完美方式。但是使用go语言的 for range 将更加容易的实现上面的功能。我们看下面的代码

package main
import (  
    "fmt"
)
func charsandbyteposition(s string) {  
    for index, rune := range s {
        fmt.printf("%c 从字节 %d 处开始\n", rune, index)
    }
}
func main() {  
    name := "迹忆客"
    charsandbyteposition(name)
}

上面代码执行结果如下

迹 从字节 0 处开始
忆 从字节 3 处开始
客 从字节 6 处开始

从上面的输出中可以很明显的看出,在utf8编码下,每个中文字符占 3 个字节


使用 rune 切片创建字符串

我们直接看示例

package main
import (  
    "fmt"
)
func main() {   
    runeslice := []rune{0x8ff9, 0x5fc6, 0x5ba2}
    str := string(runeslice)
    fmt.println(str)
}

上面代码输出结果如下

迹忆客

在上面的程序中 runeslice 包含 迹忆客 十六进制字符串的unicode代码点。

查看笔记

扫码一下
查看教程更方便
网站地图