Newbie using empty interface - is this a punishable offense?

polaris · · 517 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Go newbie here. I am working on a package that encodes structs into XML for making requests to a service. I&#39;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&#39;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:&#34;function&#34;` } </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&#39;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 &#34;Function&#34; 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 &#34;Content&#34; 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. &#34;Be very explicit&#34; 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&#39;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&#39;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

517 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传