猿问

自定义结构的 UnmarshalYAML 接口的实现

我有以下结构、接口和函数:


type FruitBasket struct {

    Capacity int `yaml:"capacity"`

    Fruits []Fruit

}


type Fruit interface {

    GetFruitName() string

}


type Apple struct {

    Name string `yaml:"name"`

}


func (apple *Apple) GetFruitName() string {

    return apple.Name

}


type tmpFruitBasket []map[string]yaml.Node


func (fruitBasket *FruitBasket) UnmarshalYAML(value *yaml.Node) error {

    var tmpFruitBasket tmpFruitBasket


    if err := value.Decode(&tmpFruitBasket); err != nil {

        return err

    }


    fruits := make([]Fruit, 0, len(tmpFruitBasket))


    for i := 0; i < len(tmpFruitBasket); i++ {

        for tag, node := range tmpFruitBasket[i] {

            switch tag {

            case "Apple":

                apple := &Apple{}

                if err := node.Decode(apple); err != nil {

                    return err

                }


                fruits = append(fruits, apple)

            default:

                return errors.New("Failed to interpret the fruit of type: \"" + tag + "\"")

            }

        }

    }


    fruitBasket.Fruits = fruits


    return nil

}

使用此代码,我可以解析以下 yaml 文件:


FruitBasket:

  - Apple:

      name: "apple1"

  - Apple:

      name: "apple2"

主要功能如下所示:


func main() {

    data := []byte(`

FruitBasket:

  - Apple:

      name: "apple1"

  - Apple:

      name: "apple2"

`)


    fruitBasket := new(FruitBasket)


    err := yaml.Unmarshal(data, &fruitBasket)


    if err != nil {

        log.Fatalf("error: %v", err)

    }


    for i := 0; i < len(fruitBasket.Fruits); i++ {

        switch fruit := fruitBasket.Fruits[i].(type) {

        case *Apple:

            fmt.Println("The name of the apple is: " + fruit.GetFruitName())

        }

    }

}

但是,我无法解析以下 yaml 字符串:


FruitBasket:

  capacity: 2

  - Apple:

      name: "apple1"

  - Apple:

      name: "apple2"

使用此字符串,我收到以下错误:error: yaml: did not find expected key.


我如何调整 UnmarshalYAML 接口的实现,以解析后面的字符串?


神不在的星期二
浏览 191回答 1
1回答

呼啦一阵风

您的 YAML 无效。每个 YAML 值都是标量、序列或映射。在capacity:处,YAML 处理器在看到第一个键时决定此级别包含一个映射。现在,在下一行,它看到- Apple:一个序列项。这在映射级别内无效;它需要下一个键,因此会给您一个错误did not find expected key。结构的修复可能如下所示:FruitBasket:&nbsp; capacity: 2&nbsp; items:&nbsp; - Apple:&nbsp; &nbsp; &nbsp; name: "apple1"&nbsp; - Apple:&nbsp; &nbsp; &nbsp; name: "apple2"请注意,序列项仍然出现在同一级别,但是由于items:没有内联值,因此这些项被解析为作为 key 值的序列items。同一缩进级别的另一个键将结束序列。然后,您可以将其加载到如下类型:type tmpFruintBasket struct {&nbsp; Capacity int&nbsp; Items []map[string]yaml.Node}
随时随地看视频慕课网APP

相关分类

Go
我要回答