去,将大写键解组为结构体。

huangapple go评论93阅读模式
英文:

Go, to unmarshal into uppercase keys

问题

根据你提供的内容,你想知道如何将未结构化的YAML数据解组为大写/ GolangCasing键,而无需预先定义结构。目前,我了解到的情况是,目前没有现成的Go软件包可以直接提供这样的功能。你可能需要自己编写代码来实现这个功能。

另外,你提到有人建议从"gopkg.in/yaml.v3"切换到"sigs.k8s.io/yaml"。然而,根据你的描述,这两个软件包都需要预先知道YAML的结构,并且需要定义翻译机制。

如果你想自己实现解组未结构化YAML的功能,你可以尝试使用正则表达式或其他字符串处理方法来解析键,并将它们转换为大写/ GolangCasing格式。这可能需要一些复杂的逻辑和处理,但是可以实现你想要的结果。

希望这可以帮助到你!如果你有任何其他问题,请随时问。

英文:

Following up on Keys are always lowercase?
#923
,

I'm looking for the easiest way for me to unmarshal an unstructured yaml into GolangCasing keys. Details --

Take a look at
https://go.dev/play/p/nIhDqoRpeK1

I.e.,

package main

import (
	"fmt"
	"log"

	"gopkg.in/yaml.v3"
)

var data = `
a: Easy!
b:
  c: 2
  d: [3, 4]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
	A string
	B struct {
		RenamedC int   `yaml:"c"`
		D        []int `yaml:",flow"`
	}
}

func main() {
	m := make(map[interface{}]interface{})

	err := yaml.Unmarshal([]byte(data), &m)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- m:\n%v\n\n", m)

	d, err := yaml.Marshal(&m)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- m dump:\n%s\n\n", string(d))
}
  • The data on line 10, are always unmarshal as lowercase keys in m.
  • In order to unmarshal then as uppercase keys, I have to pre-define a struct, like on line 19.
  • However, the challenge I'm facing is that I'm dealing with unstructured yaml, i.e., I don't know their struct ahead of time.

One follow up comment says that they "are switching from gopkg.in/yaml.v3 to sigs.k8s.io/yaml", but reading the docs of sigs.k8s.io/yaml, it looks to me that they still need to know the structure of yaml, and have also need to define the translation mechanism ahead of the time.

Is there any easy way to unmarshal unstructured yaml as uppercase / GolangCasing keys? What's the easiest way to do that? If no Go packages are providing such functionality out of the box, then is any of them have plugin/callbacks that allow me to easily do the translation myself?

答案1

得分: 1

你可以声明一个自定义的键类型,该类型实现了yaml.Unmarshaler接口。

类似这样:

type MyKey string

func (k *MyKey) UnmarshalYAML(n *yaml.Node) error {
    var s string
    if err := n.Decode(&s); err != nil {
        return err
    }
    *k = MyKey(strings.ToUpper(s))
    return nil
}

然后将其用作映射的键。

m := make(map[MyKey]any)

你可以在这里查看示例代码:https://go.dev/play/p/k9r98EPQcy4

英文:

You can declare a custom key type that implements the yaml.Unmarshaler interface.

Something like this:

type MyKey string

func (k *MyKey) UnmarshalYAML(n *yaml.Node) error {
	var s string
	if err := n.Decode(&s); err != nil {
		return err
	}
	*k = MyKey(strings.ToUpper(s))
	return nil
}

And then use it as the map's key.

m := make(map[MyKey]any)

https://go.dev/play/p/k9r98EPQcy4

huangapple
  • 本文由 发表于 2023年2月22日 23:40:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75535015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定