Advertisement
Guest User

Untitled

a guest
May 8th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.46 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. )
  8.  
  9. // The goal: allow assignment to a go struct field based on the name that field
  10. // is tagged with (specifically it's json-tagged name).
  11.  
  12. type Wham struct {
  13. Username string `json:"username,omitempty"`
  14. Password string `json:"password"`
  15. ID int64 `json:"_id"`
  16. Homebase string `json:"homebase"`
  17. }
  18.  
  19. func main() {
  20. w := Wham{
  21. Username: "maria",
  22. Password: "hunter2",
  23. ID: 42,
  24. Homebase: "2434 Main St",
  25. }
  26. fmt.Printf("%+v\n", w)
  27. SetField(&w, "username", "larry")
  28. fmt.Printf("%+v\n", w)
  29. }
  30.  
  31. func SetField(item interface{}, fieldName string, value interface{}) error {
  32. v := reflect.ValueOf(item).Elem()
  33. if !v.CanAddr() {
  34. return fmt.Errorf("cannot assign to the item passed, item must be a pointer in order to assign")
  35. }
  36. // It's possible we can cache this, which is why precompute all these ahead of time.
  37. findJsonName := func(t reflect.StructTag) (string, error) {
  38. if jt, ok := t.Lookup("json"); ok {
  39. return strings.Split(jt, ",")[0], nil
  40. }
  41. return "", fmt.Errorf("tag provided does not define a json tag", fieldName)
  42. }
  43. fieldNames := map[string]int{}
  44. for i := 0; i < v.NumField(); i++ {
  45. typeField := v.Type().Field(i)
  46. tag := typeField.Tag
  47. jname, _ := findJsonName(tag)
  48. fieldNames[jname] = i
  49. }
  50.  
  51. fieldNum, ok := fieldNames[fieldName]
  52. if !ok {
  53. return fmt.Errorf("field %s does not exist within the provided item")
  54. }
  55. fieldVal := v.Field(fieldNum)
  56. fieldVal.Set(reflect.ValueOf(value))
  57. return nil
  58. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement