Maison > développement back-end > Golang > le corps du texte

Comment puis-je réutiliser une structure d'un package tiers tout en modifiant le comportement de marshalling des champs individuels ?

PHPz
Libérer: 2024-02-10 08:18:08
avant
981 Les gens l'ont consulté

Comment puis-je réutiliser une structure dun package tiers tout en modifiant le comportement de marshalling des champs individuels ?

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 !

Contenu de la question

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&#160;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&#160;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)
}
Copier après la connexion

Voici le lien Go Playground pour le code ci-dessus : https://go.dev/play/p/ojiPv4ylCEq

Solution de contournement

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!