如何以通用方式引用嵌套的映射(map)?

huangapple go评论104阅读模式
英文:

How to reference a nested map in a generic fashion

问题

我正在尝试从已解组的 YAML 文件中访问类似于 services 键的嵌套字段。就我所知,我不想构建一个反映 YAML 文件结构的 struct,因为它可能不总是采用这种形式。YAML 文件的结构如下所示:

declared-services:
    Cloudant:
        label: cloudantNoSQLDB
        plan: Lite
applications:
- name: myProject
  memory: 512M
  instances: 1
  random-route: true
  buildpack: java
  services:
  - Cloudant
  timeout: 180
env:
  services_autoconfig_excludes: cloudantNoSQLDB=config

代码如下所示:

import "gopkg.in/yaml.v2"

func getManifestConfig() *Manifest {
    wd, _ := os.Getwd()
    manPath := wd + "/JavaProject/" + manifest
    var man map[string]interface{}
    f, err := ioutil.ReadFile(manPath)
    if err != nil {
        e(err) // 打印错误消息的不相关方法
    }

    yaml.Unmarshal(f, &man)
    fmt.Println(man["applications"]) // 这将打印 applications 下的所有内容
    fmt.Println(man["applications"].(map[string]interface{})["services"]) // 报错:接口转换失败:interface {} 是 []interface {},而不是 map[string]interface {}
    return nil
}

以上是要翻译的内容。

英文:

I'm trying to access a nested field like the services key for example from a yaml file I unmarshalled. For what it's worth I don't want to have to build a struct that reflects the structure of the yaml file since it may not always take this form. The yaml file looks like the following:

<!-- language: yaml -->

declared-services:
    Cloudant:
        label: cloudantNoSQLDB
        plan: Lite
applications:
- name: myProject
  memory: 512M
  instances: 1
  random-route: true
  buildpack: java
  services:
  - Cloudant
  timeout: 180
env:
  services_autoconfig_excludes: cloudantNoSQLDB=config

The code looks like this
<!-- language: go -->

import &quot;gopkg.in/yaml.v2&quot;

func getManifestConfig() *Manifest {
    wd, _ := os.Getwd()
    manPath := wd + &quot;/JavaProject/&quot; + manifest
    var man map[string]interface{}
    f, err := ioutil.ReadFile(manPath)
    if err != nil {
        e(err) //irrelevant method that prints error messages
    }

    yaml.Unmarshal(f, &amp;man)
    fmt.Println(man[&quot;applications&quot;]) //This will print all the contents under applications 
    fmt.Println(man[&quot;applications&quot;].(map[string]interface{})[&quot;services&quot;]) //panic: interface conversion: interface {} is []interface {}, not map[string]interface {}
    return nil
}

答案1

得分: 0

我认为你的意图是使用一个映射来处理applications。如果是这样的话,请删除文本“applications:”后面的“-”符号:

declared-services:
    Cloudant:
        label: cloudantNoSQLDB
        plan: Lite
applications:
  name: myProject
  memory: 512M
  instances: 1
  random-route: true
  buildpack: java
  services:
  - Cloudant
  timeout: 180
env:
  services_autoconfig_excludes: cloudantNoSQLDB=config

applications字段作为map[interface{}]interface{}进行访问:

fmt.Println(man["applications"].(map[interface{}]interface{})["services"])

调试此类问题的一个好方法是使用"%#v"打印值:

fmt.Printf("%#v\n", man["applications"])
// 输出带有“-”的结果:
// []interface {}{map[interface {}]interface {}{"buildpack":"java", "services":[]interface {}{"Cloudant"}, "timeout":180, "name":"myProject", "memory":"512M", "instances":1, "random-route":true}}

// 输出不带有“-”的结果:
// map[interface {}]interface {}{"instances":1, "random-route":true, "buildpack":"java", "services":[]interface {}{"Cloudant"}, "timeout":180, "name":"myProject", "memory":"512M"}

请注意,我只翻译了你提供的代码部分,其他内容我将忽略。

英文:

I think your intent is to use a mapping for applications. If so, delete the "-" following the text "applications:":

declared-services:
    Cloudant:
        label: cloudantNoSQLDB
        plan: Lite
applications:
  name: myProject
  memory: 512M
  instances: 1
  random-route: true
  buildpack: java
  services:
  - Cloudant
  timeout: 180
env:
  services_autoconfig_excludes: cloudantNoSQLDB=config

Access the applications field as a map[interface{}]interface{}:

fmt.Println(man[&quot;applications&quot;].(map[interface{}]interface{})[&quot;services&quot;])

A good way to debug issues like this is to print the value with "%#v":

fmt.Printf(&quot;%#v\n&quot;, man[&quot;applications&quot;])
// output with the &quot;-&quot;
// []interface {}{map[interface {}]interface {}{&quot;buildpack&quot;:&quot;java&quot;, &quot;services&quot;:[]interface {}{&quot;Cloudant&quot;}, &quot;timeout&quot;:180, &quot;name&quot;:&quot;myProject&quot;, &quot;memory&quot;:&quot;512M&quot;, &quot;instances&quot;:1, &quot;random-route&quot;:true}}

// output without the &quot;-&quot;:
// map[interface {}]interface {}{&quot;instances&quot;:1, &quot;random-route&quot;:true, &quot;buildpack&quot;:&quot;java&quot;, &quot;services&quot;:[]interface {}{&quot;Cloudant&quot;}, &quot;timeout&quot;:180, &quot;name&quot;:&quot;myProject&quot;, &quot;memory&quot;:&quot;512M&quot;}

huangapple
  • 本文由 发表于 2017年2月25日 07:55:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/42450240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定