Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "reflect"
- "strings"
- )
- // The goal: allow assignment to a go struct field based on the name that field
- // is tagged with (specifically it's json-tagged name).
- type Wham struct {
- Username string `json:"username,omitempty"`
- Password string `json:"password"`
- ID int64 `json:"_id"`
- Homebase string `json:"homebase"`
- }
- func main() {
- w := Wham{
- Username: "maria",
- Password: "hunter2",
- ID: 42,
- Homebase: "2434 Main St",
- }
- fmt.Printf("%+v\n", w)
- SetField(&w, "username", "larry")
- fmt.Printf("%+v\n", w)
- }
- func SetField(item interface{}, fieldName string, value interface{}) error {
- v := reflect.ValueOf(item).Elem()
- if !v.CanAddr() {
- return fmt.Errorf("cannot assign to the item passed, item must be a pointer in order to assign")
- }
- // It's possible we can cache this, which is why precompute all these ahead of time.
- findJsonName := func(t reflect.StructTag) (string, error) {
- if jt, ok := t.Lookup("json"); ok {
- return strings.Split(jt, ",")[0], nil
- }
- return "", fmt.Errorf("tag provided does not define a json tag", fieldName)
- }
- fieldNames := map[string]int{}
- for i := 0; i < v.NumField(); i++ {
- typeField := v.Type().Field(i)
- tag := typeField.Tag
- jname, _ := findJsonName(tag)
- fieldNames[jname] = i
- }
- fieldNum, ok := fieldNames[fieldName]
- if !ok {
- return fmt.Errorf("field %s does not exist within the provided item")
- }
- fieldVal := v.Field(fieldNum)
- fieldVal.Set(reflect.ValueOf(value))
- return nil
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement