dpl9717 2015-12-15 20:44
浏览 123
已采纳

转到YAML解析器静默失败

I'm trying to get simple YAML parsing in go working with gopkg.in/yaml.v2.

From the documentation:

Maps and pointers (to a struct, string, int, etc) are accepted as out values. If an internal pointer within a struct is not initialized, the yaml package will initialize it if necessary for unmarshalling the provided data. The out parameter must not be nil.

The type of the decoded values should be compatible with the respective values in out. If one or more values cannot be decoded due to a type mismatches, decoding continues partially until the end of the YAML content, and a *yaml.TypeError is returned with details for all missed values.

Note the important bits here: "pointer within struct initialized if nec'y", and "yaml.TypeError returned if a value can't be decoded".

Now:

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
)

type YamlTypeA struct {
    D string    `yaml: "d"`
    E string    `yaml: "e"`
}

type YamlTypeB struct {
    F string    `yaml: "f"`
}

type YamlTypeC struct {
    TypeA   *YamlTypeA      `yaml: "a"`
    TypeB   []YamlTypeB `yaml: "b"`
}

func main() {
    var yamlObj YamlTypeC

    text := []byte(`
---
a:  
   d: foo 
   e: bar
b: [{f: "fails"},
    {f: "completely"}]
`)

    err := yaml.Unmarshal(text,&yamlObj)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println("OK")
    fmt.Printf("TypeA.D: %s
", yamlObj.TypeA.D)
    fmt.Printf("I have %d TypeB
", len(yamlObj.TypeB))
}

yields

 OK
 panic: runtime error: invalid memory address or nil pointer dereference
 [signal 0xb code=0x1 addr=0x0 pc=0x4014b3]

which appears to violate the promises made in the documentation jointly. If I make the nested YamlTypeA immediate instead of a pointer, the result is that the output value is not touched, still no error:

 OK
 TypeA.D: 
 I have 0 TypeB

What gives here? Is it just broken / poorly documented? How can you get nested struct values to parse out of YAML? (Using maps of maps is cumbersome and not at all a solution here.)

  • 写回答

1条回答 默认 最新

  • douqinlin5094 2015-12-15 20:50
    关注

    You have spaces in your struct tags, so they're being ignored:

    type YamlTypeA struct {
        D string `yaml:"d"`
        E string `yaml:"e"`
    }
    
    type YamlTypeB struct {
        F string `yaml:"f"`
    }
    
    type YamlTypeC struct {
        TypeA *YamlTypeA  `yaml:"a"`
        TypeB []YamlTypeB `yaml:"b"`
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误