rune和string

152 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

1. 引入

string

string 类型的本质是一连串8个bit的字节, string 字符串可以直接转换成[]byte类型

字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。

Unicode 和 UTF-8

一开始计算机使用的是ASCII码,ASCII码用7位表示128个字符,包含英文字母,标点符号和数字等

Unicode编码出现,是的能够表示除了英语之外的其他语言,Go代码使用的是UTF-8的编码方式。

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字元编码,它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码:

UTF-8所需字节注释
0zzzzzzz(00-7F)1个字节ASCII字元范围,位元组由零开始
110yyyyy(C0-DF) 10zzzzzz(80-BF)2个字节第一个位元组由110开始,接著的位元组由10开始
1110xxxx(E0-EF) 10yyyyyy 10zzzzzz3个字节第一个位元组由1110开始,接著的位元组由10开始
11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz4个字节将由11110开始,接著的位元组由10开始

rune的定义

int32的别名,几乎在所有方面等同于int32,它用来区分字符值和整数值

Go 语言的字符有以下两种:

  • uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
  • rune类型,代表一个 UTF-8字符。

Go里面双引号是字符串,单引号是字符,rune。

当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串。

rune类型实际是一个int32。rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。

举个例子

s := "hello 你好"
fmt.Println(len(s),reflect.TypeOf(s)) // 打印变量s的长度和类型  12 string
fmt.Printf(""%s"'s type is %T",s,s)// "hello 你好"'s type is string

中文字符在uincode下面占2个字节,在utf-8编码下面占3个字节,Go代码使用的是UTF-8的编码方式。所以字符串总的长度是12,5(hellp)+1(空格)+6(两个中文字2*3)

2. 操作

A 修改字符串

要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。

B 遍历字符串

for _,v := range s {
   fmt.Printf(" "%v"'s type is %T \n",v,v)
}

结果

"104"'s type is int32 
 "101"'s type is int32 
 "108"'s type is int32 
 "108"'s type is int32 
 "111"'s type is int32 
 "32"'s type is int32 
 "20320"'s type is int32 

打印出来的类型是rune

C 打印变量的两种方法

1.使用reflect的TypeOf方法

s := "hello world"
fmt.Println(len(s),reflect.TypeOf(s)) // 打印变量s的长度和类型  11 string

2. 使用Printf中的占位符%T

fmt.Printf(""%s"'s type is %T",s,s) // "hello world"'s type is string

%d 十进制 %T 查看类型 %v 查看值(任何类型都可以调用) %b 二进制 %o 八进制 %x 十六进制 %s 字符串 %f 浮点数

3. 总结

  1. Rune 是golang中的一种数据类型,底层类型是int32,用来存储unicode code-point.
  2. 两种方式可以打印变量的类型,占位符%T和reflect.TypeOf()方法

参考文献

go 变量 常量 byte rune 类型转换

go中的rune