يمكن أن يكون تحليل YAML إلى بنية في Go أمرًا مباشرًا. ومع ذلك، عندما يمكن أن يمثل حقل YAML عدة بنيات محتملة، تصبح المهمة أكثر تعقيدًا. تستكشف هذه المقالة نهجًا ديناميكيًا باستخدام حزمة Go's YAML.
بالنسبة إلى Yaml v2، يمكن استخدام النهج التالي:
type yamlNode struct {
unmarshal func(interface{}) error
}
func (n *yamlNode) UnmarshalYAML(unmarshal func(interface{}) error) error {
n.unmarshal = unmarshal
return nil
}
type Spec struct {
Kind string `yaml:"kind"`
Spec interface{} `yaml:"-"
}
func (s *Spec) UnmarshalYAML(unmarshal func(interface{}) error) error {
type S Spec
type T struct {
S `yaml:",inline"`
Spec yamlNode `yaml:"spec"`
}
obj := &T{}
if err := unmarshal(obj); err != nil {
return err
}
*s = Spec(obj.S)
switch s.Kind {
case "foo":
s.Spec = new(Foo)
case "bar":
s.Spec = new(Bar)
default:
panic("kind unknown")
}
return obj.Spec.unmarshal(s.Spec)
}
بالنسبة لـ Yaml v3، يختلف النهج قليلاً:
type Spec struct {
Kind string `yaml:"kind"`
Spec interface{} `yaml:"-"
}
func (s *Spec) UnmarshalYAML(n *yaml.Node) error {
type S Spec
type T struct {
*S `yaml:",inline"`
Spec yaml.Node `yaml:"spec"`
}
obj := &T{S: (*S)(s)}
if err := n.Decode(obj); err != nil {
return err
}
switch s.Kind {
case "foo":
s.Spec = new(Foo)
case "bar":
s.Spec = new(Bar)
default:
panic("kind unknown")
}
return obj.Spec.Decode(s.Spec)
}
تسمح تقنيات التنظيم الديناميكي هذه بالتحليل المرن لحقول YAML في مجموعة محدودة من البنيات، مما يوفر حلاً أكثر أناقة وكفاءة من الحل البديل المقترح. لا تتردد في استكشاف مقتطفات التعليمات البرمجية المقدمة وتحسين النهج بناءً على متطلباتك المحددة.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3