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 關注
- 470 瀏覽
添加回答
舉報