Golang常见问题解答介绍了有关地图和切片的指针:
映射和切片值的行为类似于指针:它们是包含指向基础映射或切片数据的指针的描述符。复制地图或切片值不会复制其指向的数据。复制接口值将复制存储在接口值中的事物。如果接口值包含一个结构,则复制接口值将复制该结构。如果接口值包含一个指针,则复制接口值将复制该指针,但不会复制它指向的数据。
在遍历内部模型切片时,
ConvertType实际上是在创建
[]Models其值的切片副本。由于该原因,Type不会更改原始结构的值。
for _, module := range int_cfg.models{}上面的代码段正在创建的副本
int_cfg.models{}。索引切片模型以指向切片模型的确切基础数组,以将值更改为:
package mainimport ( "fmt" "log" "strings" "gopkg.in/yaml.v2")//internal config model for parsingtype InternalModel struct { Models []Model2 `yaml:"models"`}type Model2 struct { Name string `yaml:"name"` Type string `yaml:"type"` Target string `yaml:"target"`}var internal_config = []byte(` models: - name: myapp type: app1 target: ./ - name: myapp2 type: app2 target: ./`)type ExternalConfig struct { Landscape []Zone `yaml:"Landscape"`}type Zone struct { Zone string `yaml:"zone"` Models []Model `yaml:"models"`}type Model struct { AppType string `yaml:"app-type"` ServiceType string `yaml:"service-type"`}var external_config = []byte(`Landscape: - zone: zone1 models: - app-type: app1 service-type: GCP - app-type: app2 service-type: AMAZON - zone: zone2 models: - app-type: app3 service-type: AZURE - app-type: app4Í service-type: HEROKU`)func main() { //This is the internal config which needs to be update internalConfiglYaml := InternalModel{} err := yaml.Unmarshal(internal_config, &internalConfiglYaml) if err != nil { log.Fatalf("error in model internalConfiglYaml: %v", err) } fmt.Printf("%+vn", internalConfiglYaml) //--------------------------Second config file-----------------------// //This is the external config yaml extConfigYaml := ExternalConfig{} // var response interface{} err = yaml.Unmarshal(external_config, &extConfigYaml) if err != nil { log.Fatalf("error in model extConfigYaml: %v", err) } fmt.Printf("%+vn", extConfigYaml) landscape := "zone1" modifiedConfig := ConvertTypes(&internalConfiglYaml, extConfigYaml, landscape) fmt.Printf("%+vn", modifiedConfig)}// ConvertTypes for changing the intConfig struct typesfunc ConvertTypes(int_cfg *InternalModel, ext_config ExternalConfig, landscape string) (out_cfg *InternalModel) { for _, module := range ext_config.Landscape { if module.Zone == landscape { for i, value := range module.Models { switch strings.Compare(value.AppType, int_cfg.Models[i].Type) { case 0: //here I hard-pred the value "GCP" but it should come from the yaml struct after parsing int_cfg.Models[i].Type = value.ServiceType // should be something like ext_config.models.service-type when the key in the struct default: } } } } return int_cfg}如果检查以上代码片段,您还将认识到我已经更改了结构。
type InternalModel struct { models []Model2 `yaml:"models"`}首字母大写以使其可导出为:
type InternalModel struct { Models []Model2 `yaml:"models"`}由于struct
InternalModelis
unexportable,因此字段
model无法解析提供的
internal_configyaml,从而导致在解组yaml后导致空的[]
slice数据。
我注意到的另一件事是您再次将字节转换为字节。没有必要。
err := yaml.Unmarshal([]byte(internal_config), &internalConfiglYaml)
所以我将其更改为:
err := yaml.Unmarshal(internal_config, &internalConfiglYaml)
因为
internal_config已经
[]byte在全局变量中使用字节声明。



