英文:
Unable to Unmarshall to types.Struct with Protobuf
问题
我正在处理一个旧版的Go应用程序,类型定义方面让我抓狂。
在某个时候,我需要返回一个值,该值的类型是types.Struct
(来自github.com/gogo/protobuf/types
)。
以下是该函数的签名:
GetDeviceConfig(ctx context.Context, in *DeviceID, opts ...grpc.CallOption) (*types.Struct, error)
我从Postgres数据库(使用GORM)中获取值,使用一个名为"config"的字符串列。它可以是任何类型的JSON。
这只是一个示例:
{"fields":{"A":{"Kind":{"string_value":"B"}},"C":{"Kind":{"string_value":"D"}}}}
当我尝试将其解组为map[string]interface{}
时,它完美运行:
err := client.DB.Where("id = ?", id, 0).First(&device).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
var dat map[string]interface{}
if err := json.Unmarshal([]byte(device.Config), &dat); err != nil {
panic(err)
}
但是我需要将其转换为types.Struct
(有效的protobuf签名,不能更改)。我最好的猜测是这样的:
// 将JSON转换为结构体
s := types.Struct{}
if err := json.Unmarshal([]byte(device.Config), &s); err != nil {
panic(err)
}
// fmt.Println(s)
但是s
是空的,没有填充任何数据。
需要帮助吗?
英文:
I am working on a legacy Go app that it's driving me crazy in terms of type definition.
At some point I need to return a value with the value types.Struct
(from github.com/gogo/protobuf/types
).
Here is the signature for the function:
GetDeviceConfig(ctx context.Context, in *DeviceID, opts ...grpc.CallOption) (*types.Struct, error)
I'm getting the value from a Postgres database (with GORM) using a string column called "config". It could be any type of JSON.
Just an example:
{"fields":{"A":{"Kind":{"string_value":"B"}},"C":{"Kind":{"string_value":"D"}}}}
When I try to unmarshall to a map[string]interface{}
it works like a charm:
err := client.DB.Where("id = ?", id, 0).First(&device).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
var dat map[string]interface{}
if err := json.Unmarshal([]byte(device.Config), &dat); err != nil {
panic(err)
}
but I need to conver it to types.Struct
(valid protobuf signature that cannot be changed). My best guess was something like this:
// convert json to struct
s := types.Struct{}
if err := json.Unmarshal([]byte(device.Config), &s); err != nil {
panic(err)
}
// fmt.Println(s)
but s
is empty. No data is populated.
Any help?
答案1
得分: 1
为了将JSON解组为Struct,你需要使用Unmarshaler,它位于jsonpb包中。以下是一个示例代码:
err := jsonpb.UnmarshalString(device.Config, &s)
[...]
你可以在jsonpb_test.go中找到更多示例。
英文:
In order to unmarshal JSON into a Struct, you need to use Unmarshaler found in the jsonpb package. Something along the following lines should work:
err := jsonpb.UnmarshalString(device.Config, &s)
[...]
You can find further examples in jsonpb_test.go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论