首页 > 后端开发 > Golang > 如何在优先考虑特定值的同时有效地合并 Go 结构?

如何在优先考虑特定值的同时有效地合并 Go 结构?

Barbara Streisand
发布: 2024-11-29 21:03:10
原创
407 人浏览过

How to Efficiently Merge Go Structs While Prioritizing Specific Values?

高效合并结构体字段

问题

考虑一个具有多个字段的 Config 结构体。您有两个这种类型的结构,具有默认值的 DefaultConfig 和从文件加载的 FileConfig。目标是合并这些结构,优先考虑 FileConfig 中的值,同时保留未设置的字段。

基于反射的解决方案

一种方法涉及使用反射来比较字段值并有选择地更新 DefaultConfig 中的字段值:

func merge(default *Config, file *Config) (*Config) {
  b := reflect.ValueOf(default).Elem()
  o := reflect.ValueOf(file).Elem()

  for i := 0; i < b.NumField(); i++ {
    defaultField := b.Field(i)
    fileField := o.Field(i)
    if defaultField.Interface() != reflect.Zero(fileField.Type()).Interface() {
      defaultField.Set(reflect.ValueOf(fileField.Interface()))
    }
  }

  return default
}
登录后复制

但是,此方法需要仔细处理零值,因为它可能会导致意外的结果覆盖。

基于编码/JSON 的解决方案

更优雅且零工作量的解决方案利用编码/json 包:

import (
  "encoding/json"
  "io/ioutil"
)

var defConfig = &Config{
  S1: "def1",
  S2: "def2",
  S3: "def3",
}

func main() {
  fileContent, err := ioutil.ReadFile("config.json")
  if err != nil {
    panic(err)
  }

  err = json.NewDecoder(bytes.NewReader(fileContent)).Decode(&defConfig)
  if err != nil {
    panic(err)
  }

  fmt.Printf("%+v", defConfig)
}
登录后复制

使用这种方法:

  • config.json 中缺少的值将保留默认值值。
  • config.json 中的值将覆盖默认值,即使它们设置为零。
  • config.json 中的显式零值将覆盖非零默认值。

以上是如何在优先考虑特定值的同时有效地合并 Go 结构?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板