栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

我可以将Go的xml.Unmarshall用于有序多态类型吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

我可以将Go的xml.Unmarshall用于有序多态类型吗?

encoding/json
包不同,您没有
Unmarshaller
接口。在您的情况下,您将必须使用
Deprer
自己建议的。

下面是一个可行的解决方案:

package mainimport (    "bytes"    "encoding/xml"    "fmt")// An interface required by any instructiontype Executer interface {    Execute() error}var factoryMap map[string]func() Executer = make(map[string]func() Executer)type Play struct {    Loops int `xml:"loops,attr"`    File  string `xml:",innerxml"`    // Body of element is file name}func (p *Play) Execute() error {    for i := 0; i < p.Loops; i++ {        fmt.Println(`o/ ` + p.File)    }    return nil}type Say struct {    Voice string `xml:",innerxml"`}func (s *Say) Execute() error {    fmt.Println(s.Voice)    return nil}// Let's register the different instructions// You can have each Instruction struct in separate files, letting each file having an initfunc init() {    factoryMap["Play"] = func() Executer { return new(Play) }    factoryMap["Say"] = func() Executer { return new(Say) }}func Unmarshal(b []byte) ([]Executer, error) {    d := xml.NewDeprer(bytes.NewReader(b))    var actions []Executer    // Finding the first Root tag    for {        v, err := d.Token()        if err != nil { return nil, err        }        if _, ok := v.(xml.StartElement); ok { break        }    }    // Looping through the rest of the tokens    // finding the start of each.    for {        v, err := d.Token()        if err != nil { return nil, err        }        switch t := v.(type) {        case xml.StartElement: // We found a start of an instruction. // Let's check the name in our factoryMap // You should check that the Instruction name actually exists. Now it panics. f := factoryMap[t.Name.Local] instr := f() // We depre the rest of the tag into the instruction struct err := d.DepreElement(instr, &t) if err != nil {     return nil, err } // Appending the populated action actions = append(actions, instr)        case xml.EndElement: // We found the end tag of the Root. We are done! return actions, nil        }    }    return nil, nil}func main() {    xml := []byte(`<Root>    <Say>Playing file</Say>    <Play loops="2">https://host/somefile.mp3</Play>    <Say>Done playing</Say></Root>`)    actions, err := Unmarshal(xml)    if err != nil {        panic(err)    }    for _, instruction := range actions {        err = instruction.Execute()        if err != nil { fmt.Println(err)        }    }}

输出:

Playing file  o/ https://host/somefile.mp3  o/ https://host/somefile.mp3  Done playing

操场

当然,此代码并不完整,但是足以让您清楚地了解如何解决问题。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/452355.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号