英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论