1 回答

TA貢獻(xiàn)1963條經(jīng)驗 獲得超6個贊
實際上,您問題中顯示的代碼除了將類型傳遞給錯誤并設(shè)置錯誤格式外,什么也沒做json.Unmarshal,因此您可以重寫函數(shù)以使其表現(xiàn)得像它一樣:
func LoadConfiguration(data []byte) (*Type1, error) {
config := &Type1{}
if err := loadConf(data, config); err != nil {
return nil, err
}
// ...
}
// "magically" accepts any type
// you could actually get rid of the intermediate function altogether
func loadConf(bytes []byte, config any) error {
if err := json.Unmarshal(bytes, config); err != nil {
return fmt.Errorf("cannot load config: %v", err)
}
return nil
}
如果代碼實際上做的不僅僅是將指針傳遞給json.Unmarshal,它可以從類型參數(shù)中獲益。
type Configurations interface {
Type1 | Type2
}
func loadConf[T Configurations](bytes []byte) (*T, error) {
config := new(T)
if err := json.Unmarshal(bytes, config); err != nil {
return nil, fmt.Errorf("cannot load config: %v", err)
}
return config, nil
}
func loadConfOther[T Configurations]() (*T, error) {
flatconfig := new(T)
// ... code
return flatconfig, nil
}
在這些情況下,您可以創(chuàng)建一個任一類型的新指針,new(T)然后json.Unmarshal負(fù)責(zé)將字節(jié)切片或文件的內(nèi)容反序列化到其中——前提是 JSON 實際上可以解組到任一結(jié)構(gòu)中。
頂層函數(shù)中的特定于類型的代碼應(yīng)該仍然不同,特別是因為您想要使用顯式具體類型實例化通用函數(shù)。所以我建議保留LoadConfiguration1and LoadConfiguration2。
func LoadConfiguration1(data []byte) (*Type1, error) {
config, err := loadConf[Type1](data)
if err != nil {
return nil, err
}
confOther, err := loadConfOther[Type1]()
if err != nil {
return nil, err
}
// ... type specific code
return config, nil
}
但是,如果特定于類型的代碼只是其中的一小部分,您可能可以為特定部分使用類型切換,盡管在您的情況下這似乎不是一個可行的選擇。我看起來像:
func LoadConfiguration[T Configuration](data []byte) (*T, error) {
config, err := loadConf[T](data)
if err != nil {
return nil, err
}
// let's pretend there's only one value of type parameter type
// type-specific code
switch t := config.(type) {
case *Type1:
// ... some *Type1 specific code
case *Type2:
// ... some *Type2 specific code
default:
// can't really happen because T is restricted to Configuration but helps catch errors if you extend the union and forget to add a corresponding case
panic("invalid type")
}
return config, nil
}
最小的游樂場示例:https ://go.dev/play/p/-rhIgoxINTZ
- 1 回答
- 0 關(guān)注
- 134 瀏覽
添加回答
舉報