1 回答

TA贡献1825条经验 获得超4个赞
但是无论我这样做,我总是在某处需要一个接口{}或在 Unmarshal 之前知道确切的类型
恰恰。
在编写代码时,实例化某些泛型类型或函数所需的具体类型ReportContainerImpl必须UnmarshalReportContainer在编译时知道。当您用实际数据填充字节片时,JSON 解组发生在运行时。
要根据某些区分值解组动态 JSON,您仍然需要一个switch.
你有更好的建议如何以一种类型(更安全)的方式解决这个问题吗?
只是放弃参数多态性。这里不太合适。保留您现在拥有的代码json.RawMessage,在 中有条件地解组动态数据,switch并返回实现ReportContainer接口的具体结构。
作为通用解决方案——当且仅当您可以克服这个先有鸡还是先有蛋的问题并在编译时使类型参数已知时,您可以编写一个最小的通用解组函数,如下所示:
func unmarshalAny[T any](bytes []byte) (*T, error) {
out := new(T)
if err := json.Unmarshal(bytes, out); err != nil {
return nil, err
}
return out, nil
}
这只是为了说明原理。请注意,它json.Unmarshal已经接受任何类型,因此如果您的泛型函数实际上除了返回并没有执行任何操作new(T),就像在我的示例中一样,它与“内联”整个事物没有什么不同,就好像它unmarshalAny不存在一样。
v, err := unmarshalAny[SomeType](src)
功能上等同于
out := &SomeType{}
err := json.Unmarshal(bytes, out)
如果您打算在 中放入更多逻辑unmarshalAny,则可能需要使用它。你的旅费可能会改变; 通常,在实际上不需要时不要使用类型参数。
- 1 回答
- 0 关注
- 479 浏览
添加回答
举报