解析为什么Go语言要使用[]rune而不是string来表示中文字符

众所周知,Go语言中有以下这些数据类型。但rune32这个go语言特有的数据类型,比较有意思却经常遭到忽视。所以今天探索学习一下这个数据类型的功能、用法。

Go基本数据类型

布尔:bool

字符串:string

整数:
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64

字节:byte ,uint8 的别名

Unicode:rune ,int32 的别名

浮点:float32 float64

复数:complex64 complex128

Go语言中的中文字符

一个趣味的测试

先做一个趣味的小测试

package main

import "fmt"

func main() {
   
	str := "你好我是climber"
	fmt.Println("字符串长度为:", len(str))
	for i := 0; i < len(str); i++ {
   
		fmt.Println("第", i+1, "个字符为:", str[i:i+1])
	}
}

结果如下:

在这里插入图片描述

如果修改输出内容为

fmt.Println("第", i+1, "个字符为:", str[i])

则结果为
在这里插入图片描述

如果我们分别给他们加上强制转换为string类型

	for i := 0; i < len(str); i++ {
   
		fmt.Println("第", i+1, "个字符为:", string(str[i:i+1]))
	}
	fmt.Println("字符串长度为:", len(str))
	for i := 0; i < len(str); i++ {
   
		fmt.Println("第", i+1, "个字符为:", string(str[i]))
	}

那么结果又是这样:

在这里插入图片描述

我们发现,所输出的分别是乱码和奇怪的字符

结果及其原因分析

通过对比我们发现,对string进行切片输出,每次输出一位,中文字符会显示为乱码。而单独输出的每一位都对应的是数字。

归纳原因,string的底层是byte数组形式存储数据的。而byte的底层实质上是type byte = uint8。字符的底层是UTF-8编码,因此对于一个汉字,需要使用3个byte进行存储,而英文字符只需要一个。

对于str[i:i+1],所输出的是一个长度为1的[]byte。因为使用切片访问时,获得的是一个新的字符串。因此相当于是“三分之一个汉字”,所以自然就会导致乱码。

对于str[i],所输出的是这一位byte的内容。因为利用索引访问时,输出的是此处原始字节值。所以输出的是数字。但对其进行强制转换,那么所获得的就是对应位置的字符了。

所以如果想通过此方法输出字符串中的一位汉字,应该是输出str[i,i+3]。具体位置需要自己算。

使用[]rune操作中文字符

rune的底层是type rune = int32。相当于4个byte,所占位置是4字节。
我们也可以打印内存地址看到。

func main() {
   
	str := []rune("你好我是climber")
	fmt.Println(str)
	fmt.Println(&str[0])
	for i := 0; i < 11; i++ {
   
		fmt.Println(&str[i])
	}
}

在这里插入图片描述

而通过内存对齐,可以实现一个位置只存储一个中文或英文字符。这样情况下,输出len(),或切片输出,也就都可以获取预期值了。


func main() {
   
	str := []rune("你好我是climber")
	fmt.Println(len(str))
	for i := 0; i < 10; i++ {
   
		fmt.Println(string(str[i : i+1]))
	}

}

在这里插入图片描述

参考资源

http://www.17bigdata.com/study/programming/it-go/it-go-240840.html
https://draveness.me/golang/docs/part2-foundation/ch03-datastructure/golang-string/

相关推荐

  1. Spring(25) 为什么使用 SpringCloud,用 Dubbo?

    2024-01-06 08:12:03       13 阅读
  2. spring为什么用三级缓存二级缓存

    2024-01-06 08:12:03       38 阅读
  3. 为什么使用jvm,直接启动类文件

    2024-01-06 08:12:03       11 阅读
  4. 为什么MySQL使用B+树跳表

    2024-01-06 08:12:03       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-06 08:12:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-06 08:12:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-06 08:12:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-06 08:12:03       18 阅读

热门阅读

  1. 怎么让视频进行加速处理并保存

    2024-01-06 08:12:03       36 阅读
  2. ElasticSearch——01全文检索

    2024-01-06 08:12:03       32 阅读
  3. 5.2 Android BCC环境搭建(eadb版 上)

    2024-01-06 08:12:03       33 阅读
  4. clickonce excel 插件发布安装的原理

    2024-01-06 08:12:03       35 阅读
  5. 贪心算法Day02

    2024-01-06 08:12:03       42 阅读
  6. 贪心算法day01

    2024-01-06 08:12:03       34 阅读
  7. 数学与高维空间研究

    2024-01-06 08:12:03       30 阅读