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 [34]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[0]) b.c[9] = 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 [34]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, 33} 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[0]) b.c[9] = 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()) }