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 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳