概念
- go默认使用Unicode字符集,同时使用utf-8作为编码方式
- go里面没有字符类型(char),而是使用byte(uint8)和rune(int32)来代表字符。
- 我们声明一个字符时,默认是rune类型,除非特别定义。 一个string变量既可以被拆分为字符,也可以被拆分为字节;前者使用rune[]切片表示,后者使用byte[]切片表示
- 一个rune值就是代表一个字符,在输入输出中经常看到类似’\U0001F3A8’,’\u2665’的就是一个rune字符(unicode字符),其中的每位都是一个16进制数
var a = 'A' // rune type
var b byte = 'a' // byte type
c:= byte('b') // byte type
本质上,byte其实都是整型类型,其中byte是uint8的别称,rune是int32的别称。例如一个byte类型的字符'a'
其实是整型数字97,对应ASCII码的字符a。
var a = 'a'
var b byte = 'a'
fmt.Printf("%T, %v", a, a) // int32, 97
fmt.Printf("%T, %v", b, b) // uint8, 97
byte类型和rune类型使用编码方式不同,其中byte是ASCII编码字符,rune是utf-8字符。
string
字符串可以为空,但不能为nil;
字符串的值不能修改,只能替换;
修改字符串时需要重新分配一次内存,之前分配的内存由gc回收(因此字符串比较低效)
[]byte字符串
[]byte字符串类型适用于字符串的拼接:
byte 字符
[]byte 字符串
[][]byte字符串数组
b1 := byte('a') // 字符
b2 := []byte("A") // 字符串
b3 := []byte{'a', 'b', 'c'} // 字符串
fmt.Printf("b1 = %c\n", b1)
fmt.Printf("b2 = %c\n", b2)
fmt.Printf("b3 = %s\n", b3)
s1 := []byte("Hello") // 字符串
s2 := []byte("World") // 字符串
s3 := [][]byte{s1, s2} // 字符串数组
s4 := bytes.Join(s3, []byte(","))
s5 := []byte{}
s5 = bytes.Join(s3, []byte("--"))
s6 := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
fmt.Printf("s1 = %s\n", s1)
fmt.Printf("s2 = %s\n", s2)
fmt.Printf("s3 = %s\n", s3)
fmt.Printf("s4 = %s\n", s4)
fmt.Printf("s5 = %s\n", s5)
fmt.Printf("%s\n", bytes.Join(s6, []byte(", ")))
b1 = a
b2 = [A]
b3 = abc
s1 = Hello
s2 = World
s3 = [Hello World]
s4 = Hello,World
s5 = Hello--World
foo, bar, baz
String和[]byte转换及使用场景
转换
// string to []byte
s1 := "hello"
b := []byte(s1)
// []byte to string
s2 := string(b)
使用场景
- 需要用做map的key时,用string,因为string可以直接比较,[]byte不可以
- 如果需要用nil来表示额外的含义,用[]byte,因为string不能取nil值,[]byte可以