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 想用@vueuse 把项目动态改成深色主题,localStorge里面的vueuse-color-scheme一开始就给我改成了dark,不知道什么原因(相关搜索:背景颜色)
  • ¥20 OPENVPN连接问题
  • ¥15 flask实现搜索框访问数据库
  • ¥15 mrk3399刷完安卓11后投屏调试只能显示一个设备
  • ¥20 白日门传奇少一个启动区服和启动服务器的快捷键,东西都是全的 , 他们说套一个出来就行了 但我就是弄不好,谁看看,
  • ¥100 如何用js写一个游戏云存档
  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题