从Golang pkg / net / interface_windows.go了解bytePtrToString()

时间:2014-05-10 03:37:12

标签: string pointers go byte slice

我试图理解这段代码从[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[:])

1 个答案:

答案 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基本上是常量切片,因此它将指向与原始字节指针相同的内存地址。

这两篇文章将帮助您更好地理解这个主题: