通过unsafe包和reflect包实现,其主要原理是拿到底层数组的指针,然后转换成[]byte或string。 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(...
在string和byte[]这两个类型中允许byte[]向string的直接转换,但是不允许byte[]向string的直接转换,写成代码大概是这样: // yte[]直接转换为string,反过来就不可以了varstr = []byte("hello world")vardata =string(a) 当然我们也可以把string和byte[]用作另一种类型的初始化,这样可以做到两个类型的通用转换:...
最后我们会通过调用copy方法实现string到[]byte的拷贝,具体实现在src/runtime/slice.go中的slicestringcopy方法,这里就不贴这段代码了,这段代码的核心思路就是:将string的底层数组从头部复制n个到[]byte对应的底层数组中去 []byte类型转换到string类型 []byte类型转换到string类型本质调用的就是runtime.slicebytetost...
rune to String func main() { str := "Hello, 中国!" rs := string2rune2(str) fmt.Println(rune2string1(rs)) } func rune2string1(rs []rune) string { return string(rs) } rune、bytes 相互转换 []rune 和 []byte 的相互转换需要先转成字符串再转换。
Go source code isalways UTF-8.A string holds arbitrary bytes.A string literal, absent byte-level escapes, always holds valid UTF-8sequences.翻译整理过来其实也就是两点:go中的代码总是用utf8编码,并且字符串能够存储任何字节。没有经过字节级别的转义,那么字符串是一个标准的utf8序列。有了前面的基础...
标准转换: // string to []bytes1:="hello"b:=[]byte(s1)// []byte to strings2:=string(b) 但有时在开源代码中,我们会看到如下的 []byte 和 string 互转的代码: funcString2Bytes(sstring)[]byte{sh:=(*reflect.StringHeader)(unsafe.Pointer(&s))bh:=reflect.SliceHeader{Data:sh.Data,Len:sh...
但是[]byte和string相互转换,就需要重新申请内存并拷贝内存了。因为Go语义中,slice的内容是可变的(mutable),而string是不可变的(immutable)。如果他们底部指向同一块数据,那么由于slice可对数据做修改,string就做不到immutable了。 []byte和string互转时的底层调用分别对应runtime/string.go中stringtoslicebyte和slicebyt...
[]byte转string更简单,直接转换指针类型即可,忽略cap字段 实现如下:funcstringTobyteSlice(sstring)[]byte{tmp1:=(*[2]uintptr)(unsafe.Pointer(&s))tmp2:=[3]uintptr{tmp1[0],tmp1[1],tmp1[1]}return*(*[]byte)(unsafe.Pointer(&tmp2))}funcbyteSliceToString(bytes[]byte)string{...
// append 内会重新分配,输出a,b s := make([]byte, 0, 0) // append 内不会重新分配,输出b,b,因为容量为1,足够append s := make([]byte, 0, 1) s1 := append(s, 'a') s2 := append(s, 'b') fmt.Println(string(s1), ",", string(s2)) 重新分配指的是:append 会检查slice大小...