php小编百草为你带来了一篇关于Golang的文章,标题是“解组动态 YAML 注释”。这篇文章将详细介绍如何在Golang中解析包含注释的YAML文件,并将注释信息与对应的数据关联起来。通过本文,你将了解到如何使用Go语言的yaml.v3包来实现这一功能,并能够在自己的项目中灵活应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的知识和技巧。让我们一起开始吧!
我想动态更改 struct
的注释并使用 yaml.unmarshal
,如下所示:
package main import ( "fmt" "reflect" "gopkg.in/yaml.v3" ) type User struct { Name string `yaml:"dummy"` } func (u *User) UnmarshalYAML(node *yaml.Node) error { value := reflect.ValueOf(*u) t := value.Type() fields := make([]reflect.StructField, 0) for i := 0; i < t.NumField(); i++ { fields = append(fields, t.Field(i)) if t.Field(i).Name == "Name" { fields[i].Tag = `yaml:"name"` // Dynamic annotation } } newType := reflect.StructOf(fields) newValue := value.Convert(newType) err := node.Decode(newValue.Interface()) // Cause error because it's not pointer return err } var dat string = `name: abc` func main() { out := User{} yaml.Unmarshal([]byte(dat), &out) fmt.Printf("%+v\n", out) }
它会导致像 panic:reflect:reflect.value.set using unaddressable value [recovered]
这样的错误,我认为这是因为 node.decode
不与指针一起使用。那么如何创建新类型的指针呢?
这是有效的更新演示:
package main import ( "fmt" "reflect" "unsafe" "gopkg.in/yaml.v3" ) type User struct { Name string `yaml:"dummy"` } func (u *User) UnmarshalYAML(node *yaml.Node) error { t := reflect.TypeOf(*u) fields := make([]reflect.StructField, 0) for i := 0; i < t.NumField(); i++ { fields = append(fields, t.Field(i)) if t.Field(i).Name == "Name" { fields[i].Tag = `yaml:"name"` // Dynamic annotation } } newType := reflect.StructOf(fields) newValue := reflect.NewAt(newType, unsafe.Pointer(u)).Elem() err := node.Decode(newValue.Addr().Interface()) return err } var dat string = `name: abc` func main() { out := User{} yaml.Unmarshal([]byte(dat), &out) fmt.Printf("%+v\n", out) }
两个关键变化:
将 newvalue.interface()
替换为 newvalue.addr().interface()
。 (参见此示例:https://www.php.cn/link/e96c7de8f6390b1e6c71556e4e0a4959 a>)
将 newvalue := value.convert(newtype)
替换为 newvalue := reflect.newat(newtype, unsafe.pointer(u)).elem()
。
我们这样做是因为 value :=reflect.valueof(*u)
中的 value
是不可寻址的(您可以使用 fmt.printf("%v", value.addr())
进行验证。它会出现错误并显示消息 panic : 不可寻址值的reflect.value.addr(
)。
以上是golang:解组动态 YAML 注释的详细内容。更多信息请关注PHP中文网其他相关文章!