5

I am trying to loop through the individual fields of a struct applying a function to each field and then return the original struct as a whole with the modified field values. Obviously, this would not present a challenge if it were for one struct but I need the function to be dynamic. For this instance, I am referencing the Post and Category struct as shown below

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

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

I then have a switch function that loops through the respective fields of the structs and depending on what value the check has, applies a function to that field's data as follows

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)

     ...
}   

How do I, in essence, re-insert the modified values after the switch statement in CheckSwitch back into the struct specified by the interface in the above example. Please let me know if you need anything else. Thanks

0

1 Answer 1

4

The variable field has type reflect.Value. Call the Set* methods on field to set the fields in the struct. For example:

 field.SetString("hello")

sets the the struct field to "hello".

You must pass a pointer to the struct if you want to retain the values:

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

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

Also, the field names must be exported.

playground example

Sign up to request clarification or add additional context in comments.

1 Comment

Hey Thanks for answering! After setting the field values would I then need to return reflect.Value? How would I re-insert this into the struct specified i.e. Post in this case for further use?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.