Golang: перебирать поля структуры, изменять их и и возвращать структуру?

#go #reflection #struct #interface

#Вперед #отражение #структура #интерфейс

Вопрос:

Я пытаюсь перебирать отдельные поля структуры, применяя функцию к каждому полю, а затем возвращать исходную структуру в целом с измененными значениями полей. Очевидно, что это не представляло бы проблемы, если бы это было для одной структуры, но мне нужно, чтобы функция была динамической. В данном случае я ссылаюсь на структуру Post и Category, как показано ниже

 type Post struct{
    fieldName           data     `check:"value1"
    ...
}

type Post struct{
    fieldName           data     `check:"value2"
    ...
}
  

Затем у меня есть функция switch, которая перебирает соответствующие поля структур и, в зависимости от того, какое значение check имеет, применяет функцию к этому полю data следующим образом

 type Datastore interface {
     ...
}

 func CheckSwitch(value reflect.Value){
    //this loops through the fields
    for i := 0; i < value.NumField(); i   { // iterates through every struct type field
        tag := value.Type().Field(i).Tag // returns the tag string
        field := value.Field(i) // returns the content of the struct type field

        switch tag.Get("check"){
            case "value1":
                  fmt.Println(field.String())//or some other function
            case "value2":
                  fmt.Println(field.String())//or some other function
            ....

        }
        ///how could I modify the struct data during the switch seen above and then return the struct with the updated values?


}
}

//the check function is used i.e 
function foo(){ 
p:=Post{fieldName:"bar"} 
check(p)
}

func check(d Datastore){
     value := reflect.ValueOf(d) ///this gets the fields contained inside the struct
     CheckSwitch(value)

     ...
}   
  

Как мне, по сути, повторно вставить измененные значения после инструкции switch в CheckSwitch обратно в структуру, указанную интерфейсом в приведенном выше примере.
Пожалуйста, дайте мне знать, если вам понадобится что-нибудь еще.
Спасибо

Ответ №1:

Переменная field имеет тип reflect.Value . Вызовите методы Set* на field , чтобы задать поля в структуре. Например:

  field.SetString("hello")
  

устанавливает в поле структуры значение «привет».

Вы должны передать указатель на структуру, если хотите сохранить значения:

 function foo(){ 
    p:=Post{fieldName:"bar"} 
    check(amp;p)
}

func check(d Datastore){
   value := reflect.ValueOf(d)
   if value.Kind() != reflect.Ptr {
      // error
   }
   CheckSwitch(value.Elem())
   ...
}
  

Кроме того, имена полей должны быть экспортированы.

пример игровой площадки

Комментарии:

1. Привет, спасибо за ответ! После установки значений полей мне нужно было бы затем возвращать reflect.Value ? Как бы мне повторно вставить это в указанную структуру, т.е. Post в данном случае для дальнейшего использования?