Go将配置结构体存入interface{}后无法转回原类型问题求解
错误原因
你的实现存在两个核心错误:
- 调用
GeneralConfigLoader时传入的是ConfigurationA的值类型,而JSON反序列化必须传入目标类型的指针才能写入数据 GeneralConfigLoader内部给json.Unmarshal传了&v,这里的v本身是interface{}类型,取它的地址后,JSON包无法识别interface{}里存储的实际类型,只会默认把JSON内容反序列化为map[string]interface{}存到v中,因此后续类型断言必然失败。
修正方案
基础版(兼容所有Go版本)
不需要在App结构体里同时存值和指针,直接存储配置的指针即可:
import ( "encoding/json" "fmt" ) const JSON = `{ "Name": "TestConfig" }` type App struct { config interface{} // 直接存储配置的指针 } // ConfigurationA 是应用A的具体配置实现 type ConfigurationA struct { Name string // ... 可在此处添加更多属性 } func (a *App) GeneralConfigLoader(jsonData string, v interface{}) (err error) { // 直接使用传入的v,调用方会传入对应配置的指针 err = json.Unmarshal([]byte(jsonData), v) if err != nil { fmt.Println("JSON数据反序列化失败") return err } a.config = v return nil } func main() { var conf ConfigurationA var a = &App{} // 调用时传入配置结构体的指针 a.GeneralConfigLoader(JSON, &conf) cfg := a.config.(*ConfigurationA) fmt.Println("cfg -> ", cfg) }
优化版(Go 1.18+ 支持泛型)
用泛型实现可以避免手动类型断言,更安全易用:
import ( "encoding/json" "fmt" ) const JSON = `{ "Name": "TestConfig" }` // 用泛型定义App,绑定对应配置类型 type App[T any] struct { config *T } // ConfigurationA 是应用A的具体配置实现 type ConfigurationA struct { Name string // ... 可在此处添加更多属性 } func (a *App[T]) GeneralConfigLoader(jsonData string) error { var cfg T err := json.Unmarshal([]byte(jsonData), &cfg) if err != nil { fmt.Println("JSON数据反序列化失败") return err } a.config = &cfg return nil } // 直接返回对应类型的配置指针,无需类型断言 func (a *App[T]) Config() *T { return a.config } func main() { // 初始化时指定配置类型 a := &App[ConfigurationA]{} _ = a.GeneralConfigLoader(JSON) fmt.Println("cfg -> ", a.Config()) }
内容的提问来源于stack exchange,提问作者lumo
相关产品推荐
相关产品推荐

