有一个多文档yaml文件,其中包含不同的文档(k8s CRD)。
我不喜欢下面的实现,看起来我正在执行不必要的解码和类型转换步骤。 帮我把 GetAll 函数写得更漂亮/更清晰。
package main
import (
"bytes"
"fmt"
"gopkg.in/yaml.v3"
)
const yamldata = `
kind: Kind1
spec1: AAA
---
kind: Kind2
spec2: BBB
`
type Meta struct {
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
}
type Kind1 struct {
Meta `json:",inline" yaml:",inline"`
Spec1 string `json:"spec1,omitempty" yaml:"spec1,omitempty"`
}
type Kind2 struct {
Meta `json:",inline" yaml:",inline"`
Spec2 string `json:"spec2,omitempty" yaml:"spec2,omitempty"`
}
func GetAll[T Kind1 | Kind2](yamldata string) (result []*T) {
dec := yaml.NewDecoder(bytes.NewBufferString(yamldata))
for {
var node yaml.Node
err := dec.Decode(&node)
if err != nil {
return
}
var meta Meta
node.Decode(&meta)
var t T
switch any(t).(type) {
case Kind1:
if meta.Kind == "Kind1" {
var k any = &Kind1{}
rzlt, ok := k.(*T)
if ok {
node.Decode(rzlt)
result = append(result, rzlt)
}
}
case Kind2:
if meta.Kind == "Kind2" {
var k any = &Kind2{}
rzlt, ok := k.(*T)
if ok {
node.Decode(k)
result = append(result, rzlt)
}
}
}
}
}
func main() {
fmt.Print(GetAll[Kind1](yamldata)[0])
fmt.Print(GetAll[Kind2](yamldata)[0])
}
将功能改进为以下形式。现在我喜欢她))))但是如果有更漂亮的选择,请不要犹豫写!
func GetAll[T Kind1 | Kind2](yamldata string) (result []*T) {
dec := yaml.NewDecoder(bytes.NewBufferString(yamldata))
for {
var m any = new(T)
err := dec.Decode(m)
if err != nil {
if err.Error() == "EOF" {
break
}
continue
}
switch k := m.(type) {
case *Kind1:
if k.Kind == "Kind1" {
result = append(result, m.(*T))
}
case *Kind2:
if k.Kind == "Kind2" {
result = append(result, m.(*T))
}
}
}
return
}