#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
в данном случае для дальнейшего использования?