Итерация по значениям структуры из встроенной структуры - PullRequest
0 голосов
/ 04 августа 2020

У меня есть следующая структура

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

Затем я создаю следующий приемник для mypackage.SomeSpecialStructType следующим образом:

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")
        }
    }

}

Как (возможно) становится очевидным из кода, я хотите использовать внедрение, чтобы встроенный тип (который я ожидал получить доступ к полям внешней структуры) мог выполнять с ними некоторые операции.

Код не работает, если num здесь 0 ( делает, так как, учитывая, что SomeSpecialStructType имеет нулевые поля, только приемник)

Я знаю, что могу просто скопировать и вставить указанный c получатель в каждую создаваемую мной структуру ChartOpts (их будет много идет), но просто пытается быть DRY здесь.

1 Ответ

1 голос
/ 04 августа 2020

Встраивание не является наследованием. Когда вы встраиваете тип структуры в другой, вы, по сути, составляете новый тип, а не расширяете встроенный тип.

type Inner struct {
  X int
}

type Outer struct {
  Inner
}

Выше, Outer - это структура, содержащая Inner. Когда вы объявляете переменную типа Outer, вы можете получить доступ к полям структуры Inner с помощью:

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

Так что на самом деле это не отличается от:

type Outer struct {
   Inner Inner
}

с той разницей, что имя поля опущено. Таким образом, вы можете сократить имя поля при доступе к переменным.

Короче: метод внутренней структуры не может получить доступ к структуре внедрения. Если вам это нужно, имейте метод конструктора для внешней структуры, который устанавливает указатель во внутренней структуре. Также передайте указатель на возвращенную структуру. Если вы копируете структуру, указатель необходимо отрегулировать.

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

func NewOuter() *Outer {
   ret:=&Outer{}
   ret.outer=ret
   return ret
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...