Bagaimanakah saya boleh menggunakan semula struktur daripada pakej pihak ketiga sambil menukar gelagat marshalling medan individu?

PHPz
Lepaskan: 2024-02-10 08:18:08
ke hadapan
1013 orang telah melayarinya

Bagaimanakah saya boleh menggunakan semula struktur daripada pakej pihak ketiga sambil menukar gelagat marshalling medan individu?

Editor PHP Zimo berada di sini untuk berkongsi petua tentang cara menggunakan semula struktur dalam pakej pihak ketiga dan menukar gelagat marshalling satu medan. Apabila kami menggunakan pakej pihak ketiga, kadangkala kami perlu menyesuaikan medan di dalamnya. Artikel ini akan memperkenalkan kaedah mudah yang boleh mencapai matlamat ini melalui pewarisan dan timpa ganti, yang bukan sahaja boleh menggunakan semula struktur asal tetapi juga memenuhi keperluan yang diperibadikan. Seterusnya, mari kita lihat kaedah pelaksanaan khusus!

Kandungan soalan

Misalkan saya mahu menyusun struct ke dalam YAML, dan struct itu sudah mempunyai semua teg YAMLnya yang ditakrifkan, kecuali satu yang ingin saya ubah. Bagaimanakah saya boleh mengubah tingkah laku medan tunggal ini tanpa mengubah struktur itu sendiri? Andaikan bahawa struktur datang daripada pakej pihak ketiga.

Berikut ialah contoh untuk ditunjukkan, dan percubaan terbaik saya. Andaikan bahawa User 结构(及其关联的 Secret struktur) datang daripada pakej pihak ketiga, jadi kami tidak boleh mengubah suainya.

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)
}
Salin selepas log masuk

Berikut ialah pautan Go Playground untuk kod di atas: https://go.dev/play/p/ojiPv4ylCEq

Penyelesaian

Ini tidak mungkin.

"Percubaan terbaik" anda ialah jalan yang betul.

Atas ialah kandungan terperinci Bagaimanakah saya boleh menggunakan semula struktur daripada pakej pihak ketiga sambil menukar gelagat marshalling medan individu?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan