Вызов метода интерфейса после отражения и переключения типа в golang - PullRequest
0 голосов
/ 04 августа 2020

У меня есть структура

type ChartOpts struct {
    Name              mypakage.MyType
    Repo              mypakage.MyType
}

Ι хочу перебрать свои поля, и если утверждение типа удовлетворено, вызывается метод для этого (утвержденного) типа.

func (chartOpts ChartOpts) BindFlags(cobCom *cobra.Command) {
    fields := reflect.TypeOf(chartOpts)
    values := reflect.ValueOf(chartOpts)
    num := fields.NumField()
    fmt.Println(fields, values, num)
    for i := 0; i < num; i++ {
        field := fields.Field(i)
        switch v := field.Type.(type) {
        case mypackage.MyType:
            field.BindPersistentFlag(cobCom)
        default:
            log.Fatal(ErrUnhandledType)
        }
    }
    

}

приведенный выше код не компилируется с этой ошибкой:

field.BindPersistentFlag undefined (type reflect.StructField has no field or method BindPersistentFlag)

почему?

Ответы [ 2 ]

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

field имеет тип reflect.StructField, это не значение поля, это его дескриптор поля структуры.

Вам нужно переключить тип значения поля:

values.Field(i)

Обратите внимание, что приведенное выше значение поля заключено в reflect.Value, поэтому извлеките значение с помощью Value.Interface():

for i := 0; i < num; i++ {
    switch v := values.Field(i).Interface().(type) {
    case mypackage.MyType:
        v.BindPersistentFlag(cobCom)
    default:
        log.Fatal(ErrUnhandledType)
    }
}

И позвоните BindPersistentFlag() на v, так как это будет типа mypackage.MyType внутри case.

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

Вам нужно использовать значение и восстановить интерфейс вне отражения:

values.Field(i).Interface().(Type).Method()

В вашем случае было бы проще переключить интерфейс:

switch v := values.Field(i).Interface().(type) {
case Type:
    v.Method()
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...