dswqz24846 2013-05-06 20:11
浏览 19
已采纳

Go中的DRY结构标签

I'm parsing XML, and at most every level of the document, there's a description.

Here's an toy example:

<obj>
    <description>outer object</description>
    <subobjA>
        <description>first kind of subobject</description>
        <foo>some goop</foo>
    </subobjA>
    <subobjB>
        <description>second kind of subobject</description>
        <bar>some other goop</bar>
    </subobjB>
</obj>

This means that every struct involved has an identical Description member, with an identical tag `xml:"description,omitempty"`.

Here's functioning code: http://play.golang.org/p/1-co6Qcm8d

I'd rather the Description tags be DRY. The obvious thing to want to do is something like:

type Description string `xml:"description,omitempty"`

and then use the type Description throughout. However, only struct members can have tags. See http://play.golang.org/p/p83UrhrN4u for what I want to write; it doesn't compile.

One could create a Description struct and embed it repeatedly, but that adds a layer of indirection when accessing.

Is there another way to go about this?

  • 写回答

1条回答 默认 最新

  • doulao3905 2013-05-07 00:30
    关注

    Embedding a re-factored Description struct (as you already suggested) is the way to go:

    (Playground)

    type describable struct{
        Description string `xml:"description"`
    }
    
    type subobjA struct {
        describable
        XMLName     xml.Name `xml:"subobjA"`
    }
    
    type subobjB struct {
        describable
        XMLName     xml.Name `xml:"subobjB"`
    }
    
    type obj struct {
        XMLName     xml.Name `xml:"obj"`
        A           subobjA
        B           subobjB
    }
    

    The mentioned layer of indirection does not exist. To cite the spec on that topic:

    A field or method f of an anonymous field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.

    Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.

    So you can do this:

    err := xml.Unmarshal([]byte(sampleXml), &sampleObj)
    fmt.Println(sampleObj.Description)
    fmt.Println(sampleObj.A.Description)
    

    sampleObj.describable.Description is promoted to be sampleObj.Description, so no further layer of indirection here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集