第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

接口及其實現(xiàn)的自定義 UnmarshalYAML 接口

接口及其實現(xiàn)的自定義 UnmarshalYAML 接口

Go
ibeautiful 2023-08-14 17:36:23
我實現(xiàn)了一個接口Fruit及其兩個實現(xiàn):Apple和Banana。我想從 yaml 文件加載數(shù)據(jù)到兩個實現(xiàn)的對象中:capacity: 4Apple:- name: "apple1"  number: 1- name: "apple2"  number: 1Banana:- name: "banana1"  number: 2我實現(xiàn)了UnmarshalYaml將數(shù)據(jù)加載到對象中的接口:package mainimport (    "errors"    "gopkg.in/yaml.v3"    "log"    "fmt")type FruitBasket struct {    Capacity int `yaml:"capacity"`    Fruits []Fruit}func NewFruitBasket() *FruitBasket {    fb := new(FruitBasket)    return fb}type Fruit interface {    GetFruitName() string    GetNumber() int}type Apple struct {    Name string `yaml:"name"`    Number int `yaml:"number"`}type Banana struct {    Name string `yaml:"name"`    Number int `yaml:"number"`}func (apple *Apple) GetFruitName() string {    return apple.Name}func (apple *Apple) GetNumber() int {    return apple.Number}func (banana *Banana) GetFruitName() string {    return banana.Name}func (banana *Banana) GetNumber() int {    return banana.Number}type tmpFruitBasket struct {    Capacity int `yaml:"capacity"`    Fruits []map[string]yaml.Node}func (fruitBasket *FruitBasket) UnmarshalYAML(value *yaml.Node) error {    var tmpFruitBasket tmpFruitBasket    if err := value.Decode(&tmpFruitBasket); err != nil {        return err    }    fruitBasket.Capacity = tmpFruitBasket.Capacity    fruits := make([]Fruit, 0, len(tmpFruitBasket.Fruits))    for i := 0; i < len(tmpFruitBasket.Fruits); i++ {        for tag, node := range tmpFruitBasket.Fruits[i] {            switch tag {            case "Apple":                apple := &Apple{}                if err := node.Decode(apple); err != nil {                    return err                }                fruits = append(fruits, apple)            case "Banana":                banana := &Banana{}                if err := node.Decode(banana); err != nil {                    return err然而,這是行不通的。似乎Apple和Banana標(biāo)簽的數(shù)據(jù)未加載。Fruits可能是因為我的結(jié)構(gòu)中缺少切片的 yaml 標(biāo)志tmpFruitBasket。但是,作為Fruit一個接口,我無法定義 yaml 標(biāo)志。將來,我想實現(xiàn)代表具體水果(例如草莓)的其他結(jié)構(gòu),實現(xiàn)該接口Fruit。關(guān)于如何解決這個問題有什么想法嗎?
查看完整描述

1 回答

?
Smart貓小萌

TA貢獻(xiàn)1911條經(jīng)驗 獲得超7個贊

這是您需要的中間類型:


type tmpFruitBasket struct {

  Capacity int

  Apple    []yaml.Node `yaml:"Apple"`

  Banana   []yaml.Node `yaml:"Banana"`

}

然后,加載函數(shù)將如下所示:


// helper to load a list of nodes as a concrete type

func appendFruits(fruits []Fruit, kind reflect.Type, input []yaml.Node) ([]Fruit, error) {

  for i := range input {

    val := reflect.New(kind).Interface()

    if err := input[i].Decode(val); err != nil {

      return nil, err

    }

    fruits = append(fruits, val.(Fruit))

  }

  return fruits, nil

}



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

    var tmp tmpFruitBasket


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

        return err

    }


    fruitBasket.Capacity = tmp.Capacity


    var fruits []Fruit

    var err error

    // sadly, there is no nicer way to get the reflect.Type of Apple / Banana

    fruits, err = appendFruits(

      fruits, reflect.TypeOf((*Apple)(nil)).Elem(), tmp.Apple)

    if err != nil {

      return err

    }

    fruits, err = appendFruits(

      fruits, reflect.TypeOf((*Banana)(nil)).Elem(), tmp.Banana)

    if err != nil {

      return err

    }


    fruitBasket.Fruits = fruits

    return nil

}

編輯:如果您堅持將每種類型排序到專用切片中,您當(dāng)然可以直接將它們鍵入為[]Appleand[]Banana并合并它們。這個答案是從您之前的問題開始深入探討動態(tài)加載不同類型的輸入問題的延續(xù)。僅當(dāng)您在某些時候不再知道靜態(tài)類型時,這樣做才有意義(例如,如果您提供 API 在運行時添加其他水果類型)。


查看完整回答
反對 回復(fù) 2023-08-14
  • 1 回答
  • 0 關(guān)注
  • 192 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號