L'éditeur PHP Zimo est là pour partager une astuce sur la façon de réutiliser les structures dans des packages tiers et de modifier le comportement de marshalling d'un seul champ. Lorsque nous utilisons un package tiers, nous devons parfois y personnaliser un champ. Cet article présentera une méthode simple permettant d'atteindre cet objectif grâce à l'héritage et à l'écrasement, qui peut non seulement réutiliser la structure originale mais également répondre à des besoins personnalisés. Examinons ensuite la méthode de mise en œuvre spécifique !
Supposons que je veuille rassembler une structure en YAML et que la structure ait déjà toutes ses balises YAML définies, à l'exception d'une que je souhaite modifier. Comment puis-je modifier le comportement de ce champ unique sans modifier la structure elle-même ? Supposons que la structure provienne d’un package tiers.
Voici un exemple à démontrer, et ma meilleure tentative. Supposons que les User
结构(及其关联的 Secret
structures) proviennent de packages tiers, nous ne pouvons donc pas les modifier.
package main import ( "fmt" "gopkg.in/yaml.v2" ) type User struct { Email string `yaml:"email"` Password *Secret `yaml:"password"` } type Secret struct { s string } // MarshalYAML implements the yaml.Marshaler interface for Secret. func (sec *Secret) MarshalYAML() (interface{}, error) { if sec != nil { // Replace `"<secret>"` with `sec.s`, and it gets the desired // behavior. But I can't change the Secret struct: return "<secret>", nil } return nil, nil } func (sec *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error { var st string if err := unmarshal(&st); err != nil { return err } sec.s = st return nil } // My best attempt at the solution: type SolutionAttempt struct { User } func (sol *SolutionAttempt) MarshalYAML() (interface{}, error) { res, err := yaml.Marshal( struct { // I don't like having to repeat all these fields from User: Email string `yaml:"email"` Password string `yaml:"password"` }{ Email: sol.User.Email, Password: sol.User.Password.s, }, ) if err != nil { return nil, err } return string(res), nil } func main() { user := &User{} var data = ` email: [email protected] password: asdf ` err := yaml.Unmarshal([]byte(data), user) if err != nil { fmt.Printf("errors! %s", err) return } buf, err := yaml.Marshal(user) if err != nil { fmt.Printf("errors! %s", err) return } // Without touching User or Secret, how can I unmarshall an // instance of User that renders the secret? fmt.Printf("marshalled output:\n%s\n", buf) /////////////////////////////////////////////////////// // attempted solution: /////////////////////////////////////////////////////// sol := &SolutionAttempt{} var data2 = ` user: email: [email protected] password: asdf ` err = yaml.Unmarshal([]byte(data2), sol) if err != nil { fmt.Printf("errors! %s", err) return } buf, err = yaml.Marshal(sol) if err != nil { fmt.Printf("errors! %s", err) return } fmt.Printf("attempted solution marshalled output:\n%s\n", buf) }
Voici le lien Go Playground pour le code ci-dessus : https://go.dev/play/p/ojiPv4ylCEq
Ceci n'est tout simplement pas possible.
Votre « meilleur essai » est le bon chemin.
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!