英文:
Interface with unknown properties
问题
我正在尝试使用frontmatter
包中的Unmarshal
方法来解析Markdown文件中的前置内容。
该函数的类型签名如下:
func Unmarshal(data []byte, v interface{}) (err error)
我已经获取了字节数据,并且我理解我需要将一个具有适当字段的接口/结构体作为第二个参数传递进去,但是我不知道我要解析的文件中的字段将是什么,而且重要的是我不要丢失数据。
该包在内部使用了yaml.v2,它提供了在解组之前定义接口的更全面的示例。
type T struct {
A string
B struct {
RenamedC int `yaml:"c"`
D []int `yaml:",flow"`
}
}
然后创建结构体t
的实例,并将指向t
的指针传递给Unmarshal
。
t := T{}
err := yaml.Unmarshal([]byte(data), &t)
据我了解,只有当YAML文件看起来像这样时,这段代码才能正常工作:
a: Easy!
b:
c: 2
d: [3, 4]
第二个示例看起来更接近我所需要的。它似乎使用了一个map[interface{}]interface{}
。
m := make(map[interface{}]interface{})
err = yaml.Unmarshal([]byte(data), &m)
我对Go相对较新,对我来说,这看起来像一个通用的map,对于读取未知值来说是理想的。
我根据自己的项目改编了这个示例,并得到了以下代码。
m := make(map[interface{}]interface{})
err := frontmatter.Unmarshal(data, &m)
但是这导致了一个运行时错误
> panic: reflect: NumField of non-struct type
完整的堆栈跟踪在这里。
我是否朝着正确的方向前进?如果是的话,出了什么问题?
英文:
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
得分: 0
原来,原始的yaml.Unmarshal
方法足够强大,即使在提供整个文件的情况下,也只会提取出前置元数据。
我最终使用的解决方案如下所示:
// 读取由前置元数据和内容组成的文件
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatal(err)
}
meta := make(map[interface{}]interface{})
yaml.Unmarshal([]byte(data), &meta)
这意味着不再需要使用frontmatter
包,而是直接使用yaml
包。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论