返回信息流```
// BytesToString convert []byte type to string type.
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// StringToBytes convert string type to []byte type.
// NOTE: panic if modify the member value of the []byte.
func StringToBytes(s string) []byte {
sp := *(*[2]uintptr)(unsafe.Pointer(&s))
bp := [3]uintptr{sp[0], sp[1], sp[1]}
return *(*[]byte)(unsafe.Pointer(&bp))
}
```
这是一条镜像帖。来源:北邮人论坛 / golang / #1295同步于 2018/11/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
这段代码实在看不懂
cc19931002
2018/11/3镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
https://golang.org/src/reflect/value.go#L1818
你可以看一下golang里面string的具体实现,你给出的代码就是强制转换了一下,直接取出来了里面存的byte数组的指针,直接作为byte数组使用,或者构造个新的string然后把元数据填好了的过程。
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
type StringHeader struct {
Data uintptr
Len int
}
结合了一下楼上给出的资源总结一下
```
type StringHeader struct {
Data uintptr
Len int
}
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
从上面可以看到SliceHeader和StringHeader的区别,多了一个Cap的变量,其中的元素是int类型。
// BytesToString convert []byte type to string type.
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
当从Byte[]到String的时候,由于String所需要的结构信息只有sizeof(StringHeader)的大小,所以对于由Slice而来的数据而言它只会访问前面的uintptr和int这两个变量。多出来的Cap变量虽然也在内存中但是却永远不会访问,因此在这种情况下直接类型强转取底层的指针然后取string是可以的。相当于发生了对象分割的复制。
func StringToBytes(s string) []byte {
sp := *(*[2]uintptr)(unsafe.Pointer(&s))
bp := [3]uintptr{sp[0], sp[1], sp[1]}
return *(*[]byte)(unsafe.Pointer(&bp))
}
而当String到Byte[]的时候,分为三步,第一步先是取地址,拿到指针,然后对指针进行类型的转换,把它转换成对应类型,此时将StringHeader以uintptr的形式进行解释。第二部就分别取数据构造SliceHeader,最后再把这个SliceHeader返回。
大致情况就如此,当然我由于没接触过Go,可能在一些语法上的解释不是那么正确,但是大体意思是一样的,如果你接触过C实现泛型的话,你会发现里面其实也是各种的类似(int*)*(char**)这样的东西。希望这个回答能帮助到你。
```