Rumah >pembangunan bahagian belakang >Golang >golang: Menghapuskan komen YAML dinamik

golang: Menghapuskan komen YAML dinamik

WBOY
WBOYke hadapan
2024-02-09 11:00:14805semak imbas

golang:解组动态 YAML 注释

editor php Baicao membawakan anda artikel tentang Golang, bertajuk "Komen YAML Dinamik Unmarshalling". Artikel ini akan memperkenalkan secara terperinci cara menghuraikan fail YAML yang mengandungi ulasan dalam Golang dan mengaitkan maklumat ulasan dengan data yang sepadan. Melalui artikel ini, anda akan belajar cara menggunakan pakej yaml.v3 bahasa Go untuk melaksanakan fungsi ini dan boleh menggunakannya secara fleksibel dalam projek anda sendiri. Sama ada anda seorang pemula atau pembangun berpengalaman, artikel ini akan memberikan anda pengetahuan dan petua yang berharga. Mari mulakan!

Kandungan soalan

Saya mahu berubah secara dinamik struct 的注释并使用 yaml.unmarshal seperti berikut:

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)
}

Ia menyebabkan perkara seperti panic:reflect:reflect.value.set using unaddressable value [recovered] 这样的错误,我认为这是因为 node.decode tidak boleh digunakan dengan penunjuk. Jadi bagaimana anda mencipta jenis penuding baharu?

Penyelesaian

Berikut ialah demo dikemas kini yang berfungsi:

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)
}

Dua perubahan utama:

  1. akan newvalue.interface() 替换为 newvalue.addr().interface(). (Lihat contoh ini: https://www.php.cn/link/e96c7de8f6390b1e6c71556e4e0a4959 a>)

  2. akan newvalue := value.convert(newtype) 替换为 newvalue := reflect.newat(newtype, unsafe.pointer(u)).elem().

    Kami melakukan ini kerana value :=reflect.valueof(*u) 中的 value 是不可寻址的(您可以使用 fmt.printf("%v", value.addr()) 进行验证。它会出现错误并显示消息 panic : 不可寻址值的reflect.value.addr().

Atas ialah kandungan terperinci golang: Menghapuskan komen YAML dinamik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Pemformatan rentetan GolangArtikel seterusnya:Pemformatan rentetan Golang