英文:
Map <-> struct type casting
问题
目前,这是我用来将map[string]interface{}转换为Message结构体的方法:
byteBlob, err := json.Marshal(messageMap)
if err != nil {
return nil, err
}
message := &Message{}
err = json.Unmarshal(byteBlob, message)
if err != nil {
return nil, err
}
我发现使用json包可以解决这个问题,但是有没有不使用json包的正确方法来进行这种转换呢?
英文:
Currently this is the method I use to convert map[string]interface{} to Message struct
byteBlob, err := json.Marshal(messageMap)
if err != nil {
return nil, err
}
message := &Message{}
err = json.Unmarshal(byteBlob, message)
if err != nil {
return nil, err
}
I found json package to hack my way through this, but what is the right way to do this conversion? obviously without using json package
答案1
得分: 2
encoding/json
包使用reflect
包来编组和解组消息。
因此,您可以直接使用reflect
来做同样的事情。如果您不需要支持嵌套结构和数组,下面的代码应该可以解决问题:
message := Message{}
v := reflect.ValueOf(&message).Elem()
for key, value := range messageMap {
field := v.FieldByName(key)
if !field.IsValid() {
// 如果您不希望处理未知值,可以将其视为错误处理
continue
}
if !field.CanSet() {
// 如果字段是私有字段,可以返回错误
continue
}
field.Set(reflect.ValueOf(value))
}
您可以在playground上进一步尝试这段代码。
英文:
The encoding/json
package makes use of the reflect
package to marshal and unmarshal messages.
So you can do the same with reflect
directly. If you don't need the support for nested structs and arrays, the following should do the trick:
message := Message{}
v := reflect.ValueOf(&message).Elem()
for key, value := range messageMap {
field := v.FieldByName(key)
if !field.IsValid() {
// or handle as error if you don't expect unknown values
continue
}
if !field.CanSet() {
// or return an error on private fields
continue
}
field.Set(reflect.ValueOf(value))
}
You can experiment further with this code in the playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论