使用泛型改造 config 包
在 Go 还不支持泛型的时代,我们对于多种类型的应对一般是写出适用于各种类型的方法,然后按需要获取的类型来调用。
这样做虽然简单且有效,但大量重复的代码总是让人觉得不够优雅。而现在,Go 1.18 推出的泛型可以很好的解决这一问题。
比如 G02 课程中的 config 包,原文使用了一系列 GetString
、GetBool
、GetInt
的方法来支持各种类型配置的获取。
在 Go 1.18 版本中,我们可以利用泛型,只用一个方法来实现上述的效果:
func Get[T any](path string, defaultValue ...interface{}) T {
if value := internalGet(path, defaultValue...); value != nil {
return value.(T)
}
// 泛型不能返回 nil,因此需要根据类型建立空变量,这样返回的会是对应类型的"空"值
var fallback T
return fallback
}
在使用的时候就可以直接:
config.Get[string]("app.name")
config.Get[int]("app.level")
config.Get[bool]("app.debug")
如果你对于泛型还不了解,推荐阅读下 Go 1.18 泛型全面讲解:一篇讲清泛型的全部,个人觉得写得挺详细的。
本帖已被设为精华帖!
本帖由系统于 2年前 自动加精
defaultValue ...interface{} 改成 T, 更加优化
viper.Get返回的是sting类型数据,如果.env设置了配置需要取int类型,按这种写法Get[int]的话就会interface {} is string, not int
这样感觉不行,类型转换那感觉有问题
比如这样的转换?
两个问题:
调用:
给 Get 函数添加了一个 bool 类型的返回值,调用这可以通过布尔值明确知道配置项是否存在,然后把默认配置项分离出来成为一个单独的GetWithDefault 函数,代码的逻辑更清晰,调用者在使用的时候也更灵活的去选择。
对于必须存在的初始化配置,还可以增加 MustGet函数: