doubeizhong5178 2016-02-12 13:05
浏览 26
已采纳

具有未知属性的接口

I'm trying to use the Unmarshal method from the frontmatter package to parse front matter from a markdown file.

The type signature for the function is as follows

func Unmarshal(data []byte, v interface{}) (err error)

I've got the byte data and I understand that I need to pass an interface/struct with the appropriate fields as the second argument—however I don't know what the fields are going to be in the files that I parse and it's important that I don't lose data.

Internally this package uses yaml.v2 which provides a more comprehensive example for defining the interface before unmarshaling.

type T struct {
    A string
    B struct {
        RenamedC int   `yaml:"c"`
        D        []int `yaml:",flow"`
    }
}

Then create an instance of the struct t and pass a pointer to t through to Unmarshal.

t := T{}

err := yaml.Unmarshal([]byte(data), &t)

As I understand, this is only going to work if the YAML looks like this:

a: Easy!
b:
  c: 2
  d: [3, 4]

The second example looks closer to what I need. Rather than creating a struct, it seems to use a map of interface{} -> interface{}.

m := make(map[interface{}]interface{})

err = yaml.Unmarshal([]byte(data), &m)

I'm relatively new to Go and to me this looks like a generic map, which would be ideal for reading in unknown values.

I've adapted the example for my own project and ended up with the following code.

m := make(map[interface{}]interface{})
err := frontmatter.Unmarshal(data, &m)

But this results in a runtime error

panic: reflect: NumField of non-struct type

Full stacktrace here.


Am I heading in the right direction? If so, what's going wrong?

  • 写回答

1条回答 默认 最新

  • dongmiyi8220 2016-02-12 14:45
    关注

    Turns out that the raw yaml.Unmarshal method is robust enough to only pick up the front matter, even when presented with the entire file.

    The solution I ended up using looks like this.

    // read file made up of front matter and content
    data, err := ioutil.ReadFile(file)
    
    if err != nil {
      log.Fatal(err)
    }
    
    meta := make(map[interface{}]interface{})
    yaml.Unmarshal([]byte(data), &meta)
    

    This means dropping the frontmatter package and using the yaml package directly.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度