What are good tips and tricks for using packages that deal very heavily with interface{} values?

blov · · 516 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m currently using the RethinkDB package which takes arguments that are mostly exclusively interface{} values and 90% of the return values are of type <code>interface{}</code> so Im doing a lot of </p> <p>log.Print (find out what values its returning)</p> <p>Then a lot of <code>value.(map[string]interface{})</code> and its gets messy especially when the maps are tested and what not. </p> <p>Just wondering if there&#39;s something I could do differently to make my code a lot of cleaner and readable. Or just for handling interface{} values in general. Should I be using Reflect or what. </p> <p>(P.s. Is the RethinkDB package my dancannon is super fantastic.)</p> <hr/>**评论:**<br/><br/>Sphax: <pre><p>Looking at the package you mention, you can take two routes:</p> <ul> <li>just pass a struct where the field names matches the fields in your row, or annotate the struct with <strong>gorethink</strong> tags just like you would do in json <a href="https://github.com/dancannon/gorethink/blob/master/encoding/decoder_test.go#L17-L19">example here</a>.</li> <li>implement <a href="https://godoc.org/github.com/dancannon/gorethink/encoding#Unmarshaler">Unmarshaler</a> on your structs and do the decoding in there. This is harder to implement by the looks of it.</li> </ul> <p>Take a look <a href="https://github.com/dancannon/gorethink/blob/master/encoding/decoder_test.go">here</a>, there&#39;s a bunch of types defined which should help you.</p></pre>The_Sly_Marbo: <pre><p>It&#39;s not the answer you&#39;re looking for, but I would avoid using libraries that make significant (unjustified) use of <code>interface{}</code>. In my opinion there are very few justified uses for <code>interface{}</code>; the main one being <code>*printf</code>, where you&#39;re explicitly intending to handle <em>anything</em>.</p> <p>If you absolutely must use libraries that overuse <code>interface{}</code>, I&#39;d make a small wrapper that specialises the APIs. For example, where you&#39;re extracting a single string, something along the lines of the following would be useful:</p> <pre><code>func GetString(key string) (value string, err error) { val, err := lib.Get(key) if err != nil { return &#34;&#34;, err } var ok bool value, ok = val.(string) if !ok { return &#34;&#34;, fmt.Errorf(&#34;want string, got %T&#34;, val) } return value, nil } </code></pre> <p>It means writing some extra code but ultimately it means a small amount of code you write once and test thoroughly, meaning the rest of your codebase interacts with concrete types.</p></pre>Sphax: <pre><p>This is kinda what redigo does with its API: <a href="https://godoc.org/github.com/garyburd/redigo/redis">https://godoc.org/github.com/garyburd/redigo/redis</a></p> <p>It works a lot with interface{} but there&#39;s a bunch of helpers to get back typed values.</p></pre>natefinch: <pre><p>I don&#39;t know RethinkDB, so it&#39;s hard for me to give specific advice. In general, my advice for using packages that expose a lot of interface{} values is: don&#39;t.</p></pre>natefinch: <pre><p>A more useful reply would be - definitely you should not need reflection. Type conversions and type switches are your friend. So, yes, you should have a lot of</p> <pre><code>val, ok := foo.(sometype) </code></pre> <p>and </p> <pre><code>switch foo := foo.(type) { case sometype: // foo is now sometype } </code></pre> <p>Probably it&#39;s best to write a persistence layer that wraps the database so you hide away all the ugliness of the casting from the DB and just get back nice strongly typed values in your main logic code. How important that is kind of depends on how big your project is, though.</p></pre>thepciet: <pre><p>The interface{} type switching isn&#39;t so bad. Can&#39;t comment on robustness and maintainability yet, but seems decently expandable, catches unhandled cases with &#39;default&#39;, and already works great with the built in marshaling libs.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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