我已经设法在Go中获得以下函数。但是我想优化/泛化代码,这样这个函数将返回一个指针,指向我传递给函数的任何值的第一个字节。目前它只适用于[]uint32,但我想用它来获得起始内存地址作为许多其他类型的*字节(即byte[], int[], string等)。
是否有一种更通用的方法来做到这一点,而不是捕捉我需要作为case语句处理的每一个类型?
进入Playground链接查看下面的代码:https://play.golang.org/p/KtNTbERQGa
package main
import (
"fmt"
"reflect"
"unsafe"
)
func ToBytePointer(data interface{}) *byte {
fmt.Println("Received type is", reflect.TypeOf(data))
switch data.(type) {
case []uint32:
typedData := data.([]uint32)
return (*byte)(unsafe.Pointer(&typedData[0]))
default:
return nil
}
}
func main() {
var data = []uint32{1, 2, 3}
var dataBytePointer = (*byte)(unsafe.Pointer(&data[0]))
fmt.Println(dataBytePointer, ToBytePointer(data))
}
谢谢你的建议,我相信我已经找到我想要的了。这是可以做到的,只需要在Go的反射包中挖掘一点点。我先回答我自己的问题,这样别人可能会觉得有帮助。
在Go语言中,获取任何已分配内存块的起始内存地址作为字节指针的简洁一行代码是:(*byte)(unsafe.Pointer(reflect.ValueOf(anyAllocatedDataGoesHere).Pointer()))
如果有人需要检查它对任何数据类型的行为,即[]uint32, []byte, string, int, struct,看看我准备的这个示例PlayGround。
https://play.golang.org/p/G5fUOCfNCSGolang没有泛型,所以我猜你需要捕获每一个类型。
此外,在您的示例中,您获得了切片中第一个元素的第一个字节,而不是传递给函数的值的第一个字节。
取决于您的应用程序是什么,您可以考虑Gob编码或protobuf(如Brad Fitz的分组缓存中使用的)。你会复制你的数据,我很确定在引擎盖下仍然有反射,但至少你得到了很好的优化复制&字节编码,这可能是一个优点,因为我怀疑一旦您有了这些字节,应用程序的下一步就是某种类型的副本。