Golang:将结构转换为偏移量为0的结构

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)?

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

Avoid using unsafe whenever possible. The above task can be done using reflection (reflect package):

var v interface{} = Big{Small{1}, 2}

rf := reflect.ValueOf(v)
s := rf.FieldByName("Small").Interface()

fmt.Printf("%#v
", s)
fmt.Printf("%#v
", s.(Small).val)

Output (try it on the Go Playground):

main.Small{val:1}
1

Notes:

This works for any field, not just the first one (at "offset 0"). This also works for named fields too, not just for embedded fields. This doesn't work for unexported fields though.

type Small struct {
    val int
}

type Big struct {
    Small
    bigval int
}

func main() {
    var v = Big{Small{10},200}
    print(v.val)
}