我试图理解这段代码从[16]字节转换为字符串:
// From: https://code.google.com/p/go/source/browse/src/pkg/net/interface_windows.go
func bytePtrToString(p *uint8) string {
a := (*[10000]uint8)(unsafe.Pointer(p))
i := 0
for a[i] != 0 {
i++
}
return string(a[:i])
}
// Type of ipl.IpAddress.String is [16]byte
str := bytePtrToString(&ipl.IpAddress.String[0])
我的意思是,指针魔术的原因是什么?不能简单地写成如下吗?
func toString(p []byte) string {
for i, b := range p {
if b == 0 {
return string(p[:i])
}
}
return string(p)
}
// Type of ipl.IpAddress.String is [16]byte
str := toString(ipl.IpAddress.String[:])
答案 0 :(得分:0)
不,不能像你提议的那样写。 你忘了[]字节不是字节数组。它的字节切片。 在内存片中只是具有指向缓冲区(字节数组,将保存数据)的指针和一些有关数组大小的信息。
a := (*[10000]uint8)(unsafe.Pointer(p))
此代码将字节指针转换为字节数组。 在go数组的字节 - 它只是字节,就像在C中。没有更多。 所以如果你要声明字节数组:
var buffer [256]byte
Go将精确分配256个字节,数组甚至没有长度。数组长度是其类型的一部分,只有编译器具有有关数组长度的信息。 为什么我们可以将字节指针转换为数组。它基本相同。
i := 0
for a[i] != 0 {
i++
}
这里我们只找到以null结尾的字符串结尾。
return string(a[:i])
这里我们使用切片操作来创建一个字符串。在Go中,string基本上是常量切片,因此它将指向与原始字节指针相同的内存地址。
这两篇文章将帮助您更好地理解这个主题: