GoYAML结构切片

时间:2016-03-12 20:02:45

标签: go yaml slice

我正在尝试学习goyaml,并且尝试从yaml生成切片时遇到一些问题。我可以将我的结构编组到这个示例yaml中,但是我无法将相同的yaml解组回到结构中。

y

结构:

 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
}

1 个答案:

答案 0 :(得分:3)

以下代码对我来说很合适,输出原始的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需要指针到结构以设置其字段。如果使用普通的struct值调用它,它只接收原始struct的 copy (因为在Go 中,所有都作为副本传递),因此无法&#39 ; t可能改变原始结构的字段。

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

您可以使用c定义和初始化c := &Configuration{},即将其定义为指向Configuration的指针,同时将其指向新的归零Configuration值。然后你可以拨打yaml.Unmarshal([]byte(yamlText), c)

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

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

此外,在上面的代码中,最初有一个小错字,现在已经修复(尽管代码仍然有用)。我写了c := &Configuration{}yaml.Unmarshal([]byte(yamlText), &c),所以我实际上将Unmarshal 指向了一个指向结构的指针,Unmarshal能够处理没有问题。