Tôi thích ứng với câu trả lời của dave và thêm tính năng đệ quy. Tôi vẫn đang làm việc trên một phiên bản thân thiện với người dùng hơn. Ví dụ, một chuỗi số trong bản đồ sẽ có thể được chuyển đổi thành int trong cấu trúc. thư viện https://github.com/mitchellh/mapstructure
package main
import (
"fmt"
"reflect"
)
func SetField(obj interface{}, name string, value interface{}) error {
structValue := reflect.ValueOf(obj).Elem()
fieldVal := structValue.FieldByName(name)
if !fieldVal.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !fieldVal.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
val := reflect.ValueOf(value)
if fieldVal.Type() != val.Type() {
if m,ok := value.(map[string]interface{}); ok {
// if field value is struct
if fieldVal.Kind() == reflect.Struct {
return FillStruct(m, fieldVal.Addr().Interface())
}
// if field value is a pointer to struct
if fieldVal.Kind()==reflect.Ptr && fieldVal.Type().Elem().Kind() == reflect.Struct {
if fieldVal.IsNil() {
fieldVal.Set(reflect.New(fieldVal.Type().Elem()))
}
// fmt.Printf("recursive: %v %v\n", m,fieldVal.Interface())
return FillStruct(m, fieldVal.Interface())
}
}
return fmt.Errorf("Provided value type didn't match obj field type")
}
fieldVal.Set(val)
return nil
}
func FillStruct(m map[string]interface{}, s interface{}) error {
for k, v := range m {
err := SetField(s, k, v)
if err != nil {
return err
}
}
return nil
}
type OtherStruct struct {
Name string
Age int64
}
type MyStruct struct {
Name string
Age int64
OtherStruct *OtherStruct
}
func main() {
myData := make(map[string]interface{})
myData["Name"] = "Tony"
myData["Age"] = int64(23)
OtherStruct := make(map[string]interface{})
myData["OtherStruct"] = OtherStruct
OtherStruct["Name"] = "roxma"
OtherStruct["Age"] = int64(23)
result := &MyStruct{}
err := FillStruct(myData,result)
fmt.Println(err)
fmt.Printf("%v %v\n",result,result.OtherStruct)
}
Sử dụng JSON làm trung gian sẽ sử dụng phản chiếu anyway .. giả sử bạn sẽ sử dụng gói 'encoding/json' stdlib để thực hiện bước trung gian đó .. Bạn có thể đưa ra một ví dụ về bản đồ và ví dụ về cấu trúc mà phương thức này có thể được sử dụng trên? –
Vâng, đó là lý do tôi đang cố gắng tránh JSON. Có vẻ như hy vọng là một phương pháp hiệu quả hơn mà tôi không biết. – tgrosinger
Bạn có thể đưa ra ví dụ về trường hợp sử dụng không? Như trong - hiển thị một số giả mã chứng minh những gì phương pháp này sẽ làm gì? –