<p>Go newbie here. I am working on a package that encodes structs into XML for making requests to a service. I've read the docs and successfully created nested structs that I can use to produce the xml I need. Most of the xml structure is static, with the exception of one set of nodes that varies widely (about 20 different variations) across the different requests I need to create. </p>
<p>To deal with this I've resorted to using the empty interface for this piece. Like so (this is a very small excerpt, btw):</p>
<pre><code>type Content struct {
Function interface{} `xml:"function"`
}
</code></pre>
<p>This allows me to dynamically build these things up, reusing the shell and choosing at runtime what struct to assign to the Function field above.</p>
<p>I feel like I'm doing something dirty. Is there a more idiomatic way to do this?</p>
<hr/>**评论:**<br/><br/>dasopranos: <pre><p>This is the correct way. There are various ways of adding type safety.</p>
<ol>
<li><p>You could create a named interface and have this as the "Function" field type instead, and then add an aribtrary method on your assignable structs that satisfy this interface.</p></li>
<li><p>You could create a method on "Content" that does the assigning. The parameter to this method could do the same as option 1. Or you could do some type assertations/checks and return an error if the argument is not of the right type.</p></li>
<li><p>You could use reflection.</p></li>
</ol>
<p>Personally i would just stick with interface{}, but be very explicit about naming the field and the struct types that can be assigned to it.</p></pre>winger_sendon: <pre><p>reflection requires interfaces as well.<br/>
reflect.TypeOf and reflect.ValueOf take an interface{}</p></pre>jetjaguar76: <pre><p>Thanks. I started going down path #1 and it felt a little convoluted. When I really think about it, this stuff is going to be buried in the internals of the package, and certainly not exposed in anyway to a consumer. And internally, a developer would have to go really far out of their way to break this. I think I will indeed stick with interface{}. Cheers.</p></pre>jeffrallen: <pre><p>Yes, this is correct way to handle unmarshaling variable data structures. "Be very explicit" means good comments and/or public documentation around this point, and using a switch on the runtime-observed format of the XML to get this back into a typesafe struct again as soon as possible.</p>
<p>Another possibility, if you've got the freedom to do so, is to negotiate with the producer of the XML, explaining why what they are doing is making life difficult for you, and get a different API endpoint to use with a cleaner XML schema. Sometimes a bigger systems view is needed to ensure less maintenance costs globally, even if you take some up-front costs to achieve it.</p>
<p>-jeff</p></pre>jimijiim: <pre><p>Yes it's dirty, especially the struct tag part.</p></pre>jetjaguar76: <pre><p>What would you suggest as an alternative?</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传