GoYAML 结构切片
GoYAML struct slices
我正在尝试学习 goyaml,但在尝试从 yaml 生成切片时遇到了一些问题。我可以将我的结构编组到这个示例 yaml 中,但我无法将相同的 yaml 解编回结构中。
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
}
在测试解组时,我遇到了反映错误,据我所知,我认为我可能需要重新设计没有结构切片的设计,我希望有人可以对此提供一些见解?
错误:
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
下面的代码对我来说工作得很好,它应该输出原始的 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
需要指向结构的 指针 才能设置其字段。如果你用一个普通的结构值调用它,它只接收原始结构的 copy (因为在 Go 中 everything 作为副本传递) ,因此不可能改变原始结构的字段。
因此,您基本上有两个选择:
您可以使用 c := &Configuration{}
定义和初始化 c
,即将其定义为指向类型 Configuration
的指针,同时将其指向一个新的、归零的 Configuration
值.然后你可以调用 yaml.Unmarshal([]byte(yamlText), c)
.
或者你可以用var c Configuration
定义c
,这意味着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
是能够毫无问题地处理。
我正在尝试学习 goyaml,但在尝试从 yaml 生成切片时遇到了一些问题。我可以将我的结构编组到这个示例 yaml 中,但我无法将相同的 yaml 解编回结构中。
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
}
在测试解组时,我遇到了反映错误,据我所知,我认为我可能需要重新设计没有结构切片的设计,我希望有人可以对此提供一些见解?
错误:
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
下面的代码对我来说工作得很好,它应该输出原始的 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
需要指向结构的 指针 才能设置其字段。如果你用一个普通的结构值调用它,它只接收原始结构的 copy (因为在 Go 中 everything 作为副本传递) ,因此不可能改变原始结构的字段。
因此,您基本上有两个选择:
您可以使用 c := &Configuration{}
定义和初始化 c
,即将其定义为指向类型 Configuration
的指针,同时将其指向一个新的、归零的 Configuration
值.然后你可以调用 yaml.Unmarshal([]byte(yamlText), c)
.
或者你可以用var c Configuration
定义c
,这意味着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
是能够毫无问题地处理。