使用泛型改造 config 包

在 Go 还不支持泛型的时代,我们对于多种类型的应对一般是写出适用于各种类型的方法,然后按需要获取的类型来调用。

这样做虽然简单且有效,但大量重复的代码总是让人觉得不够优雅。而现在,Go 1.18 推出的泛型可以很好的解决这一问题。

比如 G02 课程中的 config 包,原文使用了一系列 GetStringGetBoolGetInt 的方法来支持各种类型配置的获取。

在 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 泛型全面讲解:一篇讲清泛型的全部,个人觉得写得挺详细的。

本帖已被设为精华帖!
本帖由系统于 1年前 自动加精
sunxyw
讨论数量: 3

defaultValue ...interface{} 改成 T, 更加优化

1年前 评论

viper.Get返回的是sting类型数据,如果.env设置了配置需要取int类型,按这种写法Get[int]的话就会interface {} is string, not int

1年前 评论

这样感觉不行,类型转换那感觉有问题
比如这样的转换?

func main() {
    var t interface{} = 2.33333
    // var p = fmt.Println

    //panic
    p(t.(bool))
    p(t.(float32))
    p(t.(int))
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!