I found this trick recently to replicate a C union in Go with unsafe.Sizeof, arrays, and some constant arithmetic. This lets you stack-allocate data that needs to be the max size of multiple other data types. So given a type A and B that you want to union, you can say
const ASize = int64(unsafe.Sizeof(*new(A))) const BSize = int64(unsafe.Sizeof(*new(B))) const diff = ASize - BSize const max = ASize - ((diff>>(bits.UintSize-1))&1)*diff var storage [max]byte *(*A)(unsafe.Pointer(&storage)) *(*B)(unsafe.Pointer(&storage)) This process can be repeated for any number of types. For example, if you wanted to represent a tagged union defined like type A = | B | C int | D (a: int, b: int) you could lower it to something like const size = int64(unsafe.Sizeof(*new(B))) const size0 = int64(unsafe.Sizeof(*new(C))) const diff = size - size0 const max = size - diff*((diff>>(bits.UintSize-1))&1) const size1 = int64(unsafe.Sizeof(*new(D))) const diff0 = size1 - max const max0 = size1 - diff0*((diff0>>(bits.UintSize-1))&1) type A struct { tag uint8 storage [max0]byte } type B struct{} type C int type D struct { a int b int } Unfortunately, the resulting code is pretty inefficient compared to interfaces or struct embedding. It might be that the use of unsafe is hindering compiler optimizations, or maybe it's an alignment issue. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5d150c6a-3ecb-4cb8-91b3-c048940294aen%40googlegroups.com.