简体   繁体   中英

Iterating through struct values from embedded struct

I have the following struct

type ChartOpts struct {
    Name              mypackage.Sometype
    Repo              mypackage.Anothertype
    mypackage.SomeSpecialStructType
}

Then I create the following receiver for mypackage.SomeSpecialStructType as follows:

func (c SomeSpecialStructType) BindFlags() {
    fields := reflect.TypeOf(c)
    values := reflect.ValueOf(c)
    num := fields.NumField()
    for i := 0; i < num; i++ {
        switch v := values.Field(i).Interface().(type) {
        case OrmosFlag:
            fmt.Printf("%#T\n", v)
            //v.BindPersistentFlag(cobCom)
            log.Println("HERE")
        default:
            log.Println("ERROR")
        }
    }

}

As (perhaps) becomes evident from the code, I want to leverage embedding so that the embedded type (that I was expecting to have access to the outer struct fields) can perform some operations on them.

The code does not works given that num is 0 here (makes since given that SomeSpecialStructType has zero fields, just a receiver)

I know I can just copy-paste the specific receiver on each and every ChartOpts struct I create (there will be plenty of them coming) but just trying to be DRY here.

Embedding is not inheritance. When you embed a struct type into another, you are essentially composing a new type, not extending the embedded type.

type Inner struct {
  X int
}

type Outer struct {
  Inner
}

Above, Outer is a struct containing Inner . When you declare a variable of type Outer , you can access the fields of the Inner struct by:

x:=Outer{}
x.Inner.X=1
x.X=1

So in fact this is no different from:

type Outer struct {
   Inner Inner
}

with the difference that the field name is omitted. So you can shortcut the field name when you access the variables.

in short: there is no way a method of an inner struct can access the embedding struct. If you need that, have a constructor method for the outer struct that sets a pointer in the inner struct. Also, pass around a pointer to the returned struct. If you copy the struct, the pointer needs to be adjusted.

type Outer struct {
   Inner
}
type Inner struct {
   X int
   o *Outer
}

func NewOuter() *Outer {
   ret:=&Outer{}
   ret.outer=ret
   return ret
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM