golang: Menghapuskan komen YAML dinamik

WBOY
Lepaskan: 2024-02-09 11:00:14
ke hadapan
762 orang telah melayarinya

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

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

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!

Label berkaitan:
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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!