Golang Go语言中如何实现反序列化提供默认值

发布于 1周前 作者 yibo5220 来自 Go语言
type ServerConfig struct {
	URL string
	Timeout time.Duration
    Size int
    A  int
    B int
    C int
}

ServerConfig 是从配置文件反序列化出来的,里面的变量如果配置文件没有提供的话,很多变量都是零值, 但是我期望里面的很多变量都是我自己定义的一个默认值。

我现在的做法是反序列化后再一个一个的判断,如果是零值,就改成我期望的值,这样感觉比较麻烦,有什么其他更好的方法吗?


Golang Go语言中如何实现反序列化提供默认值

更多关于Golang Go语言中如何实现反序列化提供默认值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

15 回复

使用 viper 读取配置。
然后类似这样定义
type RPCConfig struct {
Host string mapstructure:"host"
Port int mapstructure:"port"
// 使用默认值
Timeout int mapstructure:"timeout,default=30"
}

更多关于Golang Go语言中如何实现反序列化提供默认值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


做配置管理的第三方库很多都支持 default tag 。
如果觉得不好用可以先用这个库 Set 一遍 github.com/creasty/defaults

先赋默认值,再反序列化

试试这样写呢
serverConfig := ServerConfig{
URL: “www.baidu.com”,
}
_ = json.Unmarshal(bytes, &serverConfig)

一般是通过 tag 实现的

我的看法是为了这么简单的需求引入一个新的库不值(你甚至只用了他的很少功能),如果是基于 tag 的反射还影响性能, 个人解决方法偏向于给这个 struct 写个 SetDefaultValue 的方法,unmarshal 完之后调用一下

func GetDefaultServerConfig() ServerConfig {
return ServerConfig{
// 你的一些默认值…
}
}

//读取配置
serverConfig := GetDefaultServerConfig()
json.Unmarshal([]byte(jsonStr), &serverConfig)

这种比较简单,我也这样用

看着有点眼熟,可以参考我自己写的一个工具库,原理就是基于反射解析 Tag 然后赋值即可:

- https://github.com/czasg/go-fill

go<br>// 依赖<br>import "<a target="_blank" href="http://github.com/czasg/go-fill" rel="nofollow noopener">github.com/czasg/go-fill</a>"<br>// 准备结构体<br>type Config struct {<br> Host string `fill:"HOST,default=localhost"`<br> Port int `fill:"PORT,default=5432"`<br> User string `fill:"USER,default=root"`<br> Password string `fill:"PASSWORD,default=root"`<br>}<br>// 初始化<br>cfg := Config{}<br>// 填充环境变量<br>_ = fill.FillEnv(&amp;cfg)<br>

<br>type Config struct {<br> ServerConfigs []ServerConfig<br>}<br>

如果 先赋默认值,再反序列化的话。针对这个情况咋搞?

#12 如果解析的是 yaml 配置的话,可以试试这种方式

https://github.com/go-yaml/yaml/issues/165#issuecomment-255223956

嗯,确实是 yaml ,感谢

在Golang(Go语言)中,反序列化(通常通过JSON解析)时提供默认值,可以通过一些技巧来实现,因为标准库中的encoding/json包本身并不直接支持在解析时设置默认值。以下是一个常用的方法,通过定义一个自定义的UnmarshalJSON方法来实现:

  1. 定义结构体和默认值: 首先,定义你的结构体,并为需要默认值的字段设置默认值。

  2. 实现UnmarshalJSON方法: 为你的结构体实现UnmarshalJSON方法,在该方法中先使用标准库的反序列化功能尝试解析JSON,然后检查哪些字段未被解析(即保持为零值),并手动设置为默认值。

示例代码:

type MyStruct struct {
    Field1 string `json:"field1"`
    Field2 int    `json:"field2"`
    // 假设Field2需要默认值100
}

func (m *MyStruct) UnmarshalJSON(data []byte) error {
    type Alias MyStruct
    aux := &struct {
        Field2 int `json:"field2,omitempty"`
        *Alias
    }{
        Alias: (*Alias)(m),
        Field2: 100, // 默认值
    }
    if err := json.Unmarshal(data, &aux); err != nil {
        return err
    }
    if aux.Field2 == 0 { // 如果JSON中没有提供field2,则保持默认值
        m.Field2 = aux.Field2
    }
    return nil
}

这种方法允许你在反序列化过程中灵活地设置默认值,同时保持结构体的其他字段正常解析。

回到顶部