如何在Go中使用基本类型设置结构字段

huangapple go评论117阅读模式
英文:

How to set struct field using base type in Go

问题

如果我定义了一个类型 type myInt64 int64,我该如何使用反射来设置它?以下是代码,但是会导致 panic:reflect.Set: value of type int64 is not assignable to type main.myInt64。

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. type myInt64 int64
  7. type MyStruct struct {
  8. Name string
  9. Age myInt64
  10. }
  11. func FillStruct(m map[string]interface{}, s interface{}) error {
  12. structValue := reflect.ValueOf(s).Elem()
  13. for name, value := range m {
  14. structFieldValue := structValue.FieldByName(name)
  15. val := reflect.ValueOf(value)
  16. structFieldValue.Set(val)
  17. }
  18. return nil
  19. }
  20. func main() {
  21. myData := make(map[string]interface{})
  22. myData["Name"] = "Tony"
  23. myData["Age"] = int64(23)
  24. result := &MyStruct{}
  25. err := FillStruct(myData, result)
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. fmt.Println(result)
  30. }
英文:

If I defined a type type myInt64 int64 how would I set it using reflection? Code below panics reflect.Set: value of type int64 is not assignable to type main.myInt64
http://play.golang.org/p/scsXq4ofk6

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. type myInt64 int64
  7. type MyStruct struct {
  8. Name string
  9. Age myInt64
  10. }
  11. func FillStruct(m map[string]interface{}, s interface{}) error {
  12. structValue := reflect.ValueOf(s).Elem()
  13. for name, value := range m {
  14. structFieldValue := structValue.FieldByName(name)
  15. val := reflect.ValueOf(value)
  16. structFieldValue.Set(val)
  17. }
  18. return nil
  19. }
  20. func main() {
  21. myData := make(map[string]interface{})
  22. myData["Name"] = "Tony"
  23. myData["Age"] = int64(23)
  24. result := &MyStruct{}
  25. err := FillStruct(myData, result)
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. fmt.Println(result)
  30. }

答案1

得分: 7

你必须为赋值提供正确的类型。没有隐式类型转换。

你可以在函数中提供一个 myInt64

  1. myData := make(map[string]interface{})
  2. myData["Name"] = "Tony"
  3. myData["Age"] = myInt64(23)

http://play.golang.org/p/sbOdAnbz8n

或者你可以在赋值过程中进行值的转换:

  1. for name, value := range m {
  2. structFieldValue := structValue.FieldByName(name)
  3. fieldType := structFieldValue.Type()
  4. val := reflect.ValueOf(value)
  5. structFieldValue.Set(val.Convert(fieldType))
  6. }

http://play.golang.org/p/kl0fEENY9b

英文:

You have to provide the correct type for the assignment. There are no implicit type conversions.

You can either provide a myInt64 to your function

  1. myData := make(map[string]interface{})
  2. myData["Name"] = "Tony"
  3. myData["Age"] = myInt64(23)

http://play.golang.org/p/sbOdAnbz8n

Or you can convert the values during assignment

  1. for name, value := range m {
  2. structFieldValue := structValue.FieldByName(name)
  3. fieldType := structFieldValue.Type()
  4. val := reflect.ValueOf(value)
  5. structFieldValue.Set(val.Convert(fieldType))
  6. }

http://play.golang.org/p/kl0fEENY9b

huangapple
  • 本文由 发表于 2015年11月21日 06:57:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/33837440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定