为了账号安全,请及时绑定邮箱和手机立即绑定

GoYAML 结构切片

GoYAML 结构切片

Go
慕斯王 2021-12-20 16:54:53
我正在尝试学习 goyaml,并且在尝试从 yaml 生成切片时遇到了一些问题。我可以将我的结构编组到这个示例 yaml 中,但我不能将相同的 yaml 解组回结构中。 input:  file:  - file: stdin  webservice:  - port: "0000"    address: 0.0.0.0processing:  regex:  - regex: ^(this)*    mapping: (1) thingoutput:  file:  - file: stdout  webservice:  - port: "0000"    address: 0.0.0.0结构:type Configuration struct{    Input ioInstance    Processing ProcessingInstance    Output ioInstance}type ioInstance struct {    File []FileInstance    Webservice []WebserviceInstance}type FileInstance struct {    File string}type WebserviceInstance struct  {    Port string    Address string}type ProcessingInstance struct {    Regex []RegexInstance}type RegexInstance struct {    Regex string    Mapping string}在测试解组时,我收到了反射错误,据我所知,我认为我可能需要在没有结构切片的情况下重新设计设计,我希望有人能对此提供一些见解?错误:panic: reflect: reflect.Value.Set using unaddressable value [recovered]    panic: reflect: reflect.Value.Set using unaddressable value [recovered]    panic: reflect: reflect.Value.Set using unaddressable value
查看完整描述

1 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

下面的代码对我来说很好用,输出原始的 yaml 文本:


package main


import "fmt"

import "gopkg.in/yaml.v2"


func main() {

    c := &Configuration{}

    yaml.Unmarshal([]byte(yamlText), c) 

    buf, _ := yaml.Marshal(c)

    fmt.Println(string(buf))

}


var yamlText = ` 

input:

  file:

  - file: stdin

  webservice:

  - port: "0000"

    address: 0.0.0.0

processing:

  regex:

  - regex: ^(this)*

    mapping: (1) thing

output:

  file:

  - file: stdout

  webservice:

  - port: "0000"

    address: 0.0.0.0

`


type Configuration struct {

    Input      ioInstance

    Processing ProcessingInstance

    Output     ioInstance

}


type ioInstance struct {

    File       []FileInstance

    Webservice []WebserviceInstance

}


type FileInstance struct {

    File string

}


type WebserviceInstance struct {

    Port    string

    Address string

}


type ProcessingInstance struct {

    Regex []RegexInstance

}


type RegexInstance struct {

    Regex   string

    Mapping string

}

输出:


input:

  file:

  - file: stdin

  webservice:

  - port: "0000"

    address: 0.0.0.0

processing:

  regex:

  - regex: ^(this)*

    mapping: (1) thing

output:

  file:

  - file: stdout

  webservice:

  - port: "0000"

    address: 0.0.0.0

(当然,你应该不会在你的实际代码忽略错误,就像我在这里做。)


编辑:


Unmarshal需要一个指向结构的指针以设置其字段。如果您使用普通结构值调用它,它只会接收原始结构的副本(因为在 Go 中所有内容都作为副本传递),因此不可能更改原始结构的字段。


因此,您基本上有两种选择:


您可以定义并初始化c用c := &Configuration{},即它定义为一个指向类型Configuration,同时将其指向一个新的,归零Configuration值。然后就可以调用了yaml.Unmarshal([]byte(yamlText), c)。


或者,您可以定义cwith var c Configuration,这意味着c不是指针,而是类型的新零值Configuration。在这种情况下,您需要在调用Unmarshal:时显式传递指向该值的指针yaml.Unmarshal([]byte(yamlText), &c)。


请注意,您传递给 Unmarshal 的指针必须指向现有 Configuration值。var c *Configuration将定义c为一个指针,但立即将其传递给Unmarshal会导致恐慌,因为它的值为nil; 它不指向现有Configuration值。


此外,在我上面的代码中,最初有一个小错字,现在已修复(尽管代码仍然有效)。我写了c := &Configuration{}and yaml.Unmarshal([]byte(yamlText), &c),所以我实际上传递Unmarshal 了一个指向 struct 的指针,它Unmarshal能够毫无问题地处理。


查看完整回答
反对 回复 2021-12-20
  • 1 回答
  • 0 关注
  • 233 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信