2.3.5 指针间的转换
在C语言中,不同类型的指针是可以显式或隐式转换的,如果是隐式只是会在编译时给出一些警告信息。但是Go语言对于不同类型的转换非常严格,任何C语言中可能出现的警告信息在Go语言中都可能是错误!指针是C语言的灵魂,指针间的自由转换也是cgo代码中经常要解决的第一个重要的问题。
在Go语言中两个指针的类型完全一致则不需要转换可以直接通用。如果一个指针类型是用type命令在另一个指针类型基础之上构建的,换言之两个指针底层是相同完全结构的指针,那么我我们可以通过直接强制转换语法进行指针间的转换。但是cgo经常要面对的是2个完全不同类型的指针间的转换,原则上这种操作在纯Go语言代码是严格禁止的。
cgo存在的一个目的就是打破Go语言的禁止,恢复C语言应有的指针的自由转换和指针运算。以下代码演示了如何将X类型的指针转化为Y类型的指针:
var p *X
var q *Y
q = (*Y)(unsafe.Pointer(p)) // *X => *Y
p = (*X)(unsafe.Pointer(q)) // *Y => *X
为了实现X类型指针到Y类型指针的转换,我们需要借助unsafe.Pointer
作为中间桥接类型实现不同类型指针之间的转换。unsafe.Pointer
指针类型类似C语言中的void*
类型的指针。
下面是指针间的转换流程的示意图:
图 2-1 X类型指针转Y类型指针
任何类型的指针都可以通过强制转换为unsafe.Pointer
指针类型去掉原有的类型信息,然后再重新赋予新的指针类型而达到指针间的转换的目的。
学员评价