Search code examples
gostructinterfaceembedding

Golang: convert struct to embedded at offset 0 struct


I have some different structs like Big with Small embedded at offset 0. How can I access Small's structure fields from code, that doesn't know anything about Big type, but it is known that Small is at offset 0?

type Small struct {
    val int
}

type Big struct {
    Small
    bigval int
}

var v interface{} = Big{}
// here i only know about 'Small' struct and i know that it is at the begining of variable
v.(Small).val // compile error

It seems that compiler is theoretically able to operate such expression, because it knows that Big type has Small type embedded at offset 0. Is there any way to do such things (maybe with unsafe.Pointer)?


Solution

  • While answer with reflection is working but it has performance penalties and is not idiomatic to Go.

    I believe you should use interface. Like this

    https://play.golang.org/p/OG1MPHjDlQ

    package main
    
    import (
        "fmt"
    )
    
    type MySmall interface {
        SmallVal() int
    }
    
    type Small struct {
        val int
    }
    
    func (v Small) SmallVal() int {
        return v.val
    }
    
    type Big struct {
        Small
        bigval int
    }
    
    func main() {
        var v interface{} = Big{Small{val: 3}, 4}
        fmt.Printf("Small val: %v", v.(MySmall).SmallVal())
    }
    

    Output:

    Small val: 3