l'éditeur php Baicao vous propose un article sur Golang, intitulé "Unmarshalling Dynamic YAML Comments". Cet article présentera en détail comment analyser les fichiers YAML contenant des commentaires dans Golang et associer les informations de commentaire aux données correspondantes. Grâce à cet article, vous apprendrez à utiliser le package yaml.v3 du langage Go pour implémenter cette fonction et pourrez l'appliquer de manière flexible dans vos propres projets. Que vous soyez débutant ou développeur expérimenté, cet article vous apportera de précieuses connaissances et conseils. Commençons!
Je souhaite changer dynamiquement struct
的注释并使用 yaml.unmarshal
comme suit :
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) }
Cela empêche des éléments comme panic:reflect:reflect.value.set using unaddressable value [recovered]
这样的错误,我认为这是因为 node.decode
d'être utilisés avec des pointeurs. Alors, comment créer un nouveau type de pointeur ?
Voici une démo mise à jour et fonctionnelle :
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) }
Deux changements clés :
volonté newvalue.interface()
替换为 newvalue.addr().interface()
. (Voir cet exemple : https://www.php.cn/link/e96c7de8f6390b1e6c71556e4e0a4959 a>)
volonté newvalue := value.convert(newtype)
替换为 newvalue := reflect.newat(newtype, unsafe.pointer(u)).elem()
.
Nous faisons cela parce que value :=reflect.valueof(*u)
中的 value
是不可寻址的(您可以使用 fmt.printf("%v", value.addr())
进行验证。它会出现错误并显示消息 panic : 不可寻址值的reflect.value.addr(
).
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!