golang中的string和byte理解

有些鸟儿是注定不会被关在牢笼里的,它们的每一片羽毛都闪耀着自由的光辉

Go语言中有两种可以储存一串字符的类型,分别是字符串stringbyte类型数组[]byte,但是他们直接并不能直接使用等于号赋值,也不能单纯的转换,而是要通过切片来进行转换。

string转换成[]byte

可以直接使用[]byte(str)强制转换。

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
var str string = "test"
var data []byte = []byte(str)

fmt.Println("string: ", str) // string: test
fmt.Println("[]byte: ", data) // []byte: [116 101 115 116]
}

可以看到[]byte输出的结果正是string的各个字符对应的ASCII码。
或者

1
2
3
4
5
6
7
8
9
func String2Bytes(s string) []byte {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
}

[]byte转换成string

要将byte数组转换成string不能直接转换,而需要将[]byte的切片转换。即使用string(数组名[:])进行转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
var data [5]byte
data[0] = 'T'
data[1] = 'E'
data[2] = 'S'
data[3] = 'T'
var str string = string(data[:])
fmt.Println("[]byte: ", data) // []byte: [84 69 83 84 0]
fmt.Println("string: ", str) // string: TEST
}

或者

1
2
// []byte to string
s2 := string(b)

再或者

1
2
3
func Bytes2String(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}

二者区别

对于[]byte与string而言,两者之间最大的区别就是string的值不能改变。这该如何理解呢?下面通过两个例子来说明。

对于[]byte来说,以下操作是可行的:

1
2
b := []byte("Hello Gopher!")
b [1] = 'T'

string,修改操作是被禁止的:

1
2
s := "Hello Gopher!"
s[1] = 'T'

而string能支持这样的操作:

1
2
s := "Hello Gopher!"
s = "Tello Gopher!"

字符串的值不能被更改,但可以被替换。