0

I have a scenario where I'm calling a function leveraging a common background worker thread that has arguments as func somefunction(data ...interface{}) to be generic and reusable across the application.

In one of the functions, the number of arguments are more and in the unction definition, I am casting the array items individually like

someVar := data[0].(string)

Now this approach is fine when I'm usually dealing with 1-2 arguments. But it becomes tedious when the number of arguments increases.

So is there a cleaner way to parse the elements into a struct in the order of their appearance?

My objective is to do this in a cleaner way rather than individually getting one from array and casting to a string variable.

Sample code explaining the scenario https://go.dev/play/p/OScAjyyLW0W

2
  • 2
    You could write a helper function that uses reflection, but it'll be slower than using type assertions and assigning manually. On the other hand, this is a weak abstraction. If you want to construct a struct value for the arguments, you should be passing a struct value in the first place. Commented Feb 22, 2022 at 17:36
  • @icza Thanks, this helped. I had to modify things a bit for which I was skeptical. But it turned out to be the best approach. Commented Feb 23, 2022 at 5:45

1 Answer 1

3

Use the reflect package to set fields on a value from a slice of interface{}. The fields must be exported.

// setFields set the fields in the struct pointed to by dest
// to args. The fields must be exported.
func setFields(dest interface{}, args ...interface{}) {
    v := reflect.ValueOf(dest).Elem()
    for i, arg := range args {
        v.Field(i).Set(reflect.ValueOf(arg))
    }
}

Call it like this:

type PersonInfo struct {  
    ID       string  // <-- note exported field names.
    Name     string
    Location string
}

var pi PersonInfo
setFields(&pi, "A001", "John Doe", "Tomorrowland")

Playground Example.

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

Comments

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.