golang 中的 sizeof:
1:
int(unsafe.Sizeof(uint32(0)))
2:
int(reflect.TypeOf(uint32(0)).Size())
golang中的 union:
package main import (
"fmt"
"reflect"
"unsafe"
) type I struct {
a int32
} type B struct {
c []int16
} func main() {
a := I{0x060302}
b := (*B)(unsafe.Pointer(&a))
fmt.Printf("%x, %d\n", a.a, a.a)
fmt.Printf("%v\n", b.c)
fmt.Printf("%v\n", b.c[])
b.c[] = 0x0008
fmt.Printf("%v\n", b.c)
fmt.Printf("%x, %d\n", a.a, a.a)
fmt.Printf("%d\n", reflect.TypeOf(b.c).Size())
fmt.Printf("%d\n", reflect.TypeOf(a).Size())
}
注意,如果你要以 (*B)(unsafe.Pointer(&a)) 这种方式来作为 union,必须保证这两个union的类型字节大小一样大,golang不会为你检查越界。上面的例子就越界了,编译和运行时,golang没有任何警告。
下面是更完善的实现:
package main import (
"fmt"
"reflect"
"unsafe"
) // ----- union begin ---------------------------------------------------
type IorBUnion interface {
toB() *B
toI() *I
} type I struct {
a int32
} func (i *I) toB() *B {
return (*B)(unsafe.Pointer(i))
} func (i *I) toI() *I {
return i
} type B struct {
c []int16
} func (b *B) toB() *B {
return b
} func (b *B) toI() *I {
return (*I)(unsafe.Pointer(b))
} // ------- union end ------------------------------------------------- type myStruct struct {
iOrB IorBUnion
aaa int
} func main() {
a := &I{0x060302}
mystruct := myStruct{a, }
b := (*B)(unsafe.Pointer(a))
fmt.Printf("%x, %d\n", a.a, a.a)
fmt.Printf("%v\n", b.c)
fmt.Printf("%v\n", b.c[])
b.c[] = 0x0008
fmt.Printf("%v\n", b.c)
fmt.Printf("%x, %d\n", a.a, a.a)
fmt.Printf("%d\n", reflect.TypeOf(b.c).Size())
fmt.Printf("%d\n", reflect.TypeOf(a).Size())
fmt.Println(b.toB())
fmt.Println(b.toI())
fmt.Println(b.toI().toB())
fmt.Println(a.toI().toB())
fmt.Println(mystruct.iOrB.toI().toB())
}