Я боролся с отражающим пакетом. Этот код ниже делает то, что я ожидаю:
package main
import (
"reflect"
"log"
)
type Car struct {
Model string
}
type Person struct {
Name string
Cars []Car
}
func ModifyIt(parent interface{},fieldName string, val interface{}) {
slice := reflect.ValueOf(parent).Elem()
nth := slice.Index(0)
//row := nth.Interface() // this line causes errors
row := nth.Interface().(Person)
elem := reflect.ValueOf(&row).Elem()
field := elem.FieldByName(fieldName)
log.Println(field.CanSet())
}
func main() {
p := []Person{Person{Name:"john"}}
c := []Car{Car{"corolla"},Car{"jetta"}}
ModifyIt(&p,"Cars",&c)
}
Однако, если я заменяю строку row := nth.Interface().(Person)
на row := nth.Interface()
, то есть удаляю утверждение типа, я получаю ошибку:
паника: отражение: вызов рефлекса. Значение.FieldByName в интерфейсе Значение
on line "field: = elem.FieldByName (fieldName)
В последние несколько часов я пробовал множество других вещей, например, пытался сделать reflect.TypeOf()
, reflect.Indirect()
и т. Д. ... для некоторых других переменных, но безуспешно.
Я читал некоторые другие вопросы, подобные этим:
отражение: вызов рефлекса. Значение.FieldByName в ptr Значение
Установить поле структуры с типом поля интерфейса
Отражение Голанга: Невозможно установить поля интерфейса, обертывающие структуру
Кажется, они говорят о том, что я плохо понимаю, как работают указатели или интерфейсы.
Итак, мой вопрос: как мне настроить поле структуры, когда структура вводится как интерфейс?
UPDATE
Я отправил решение в качестве ответа, но я не уверен, является ли это правильным или безопасным способом выполнения действий. Я надеюсь, что кто-то может объяснить или опубликовать лучшее решение.