Is interface{} acceptable? Discuss.

agolangf · · 482 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>If it&#39;s not and sacrificing type safety, then why is it there? If it&#39;s there, why using it is considered bad.? Isn&#39;t it just like an &#34;any&#34; type in many languages (except there is a <code>nil</code> in Go). I&#39;ve heard arguments about this being a bad practices only from the community at large, but never from the Go official documentations or the core team itself. Why?</p> <hr/>**评论:**<br/><br/>peterbourgon: <pre><p>You can&#39;t make a single, general statement like <code>interface{} is acceptable</code> or <code>interface{} is bad</code>. It&#39;s a tool that can be used. It&#39;s often overused by folks new to the language. To say more requires context.</p></pre>gac_web: <pre><p>interface {}, 99% of the time implies reflection, which means no compiler optimization so a radical hit in performance, and obviously the compile time type safety is thrown out of the window. Don&#39;t get me started on Go reflection which is so leaky it hurts ( it leaks Go internals ).</p> <p>Now it depends on your background : </p> <p>if you come from C/Ruby/Python/JS/PHP and co : you might not even know what a generic or a type class is, so you might not even care about type correctness at compile time.</p> <p>if you come from C#,C++,Java or any ML language(Ocaml, F#) , it definitely feels extremely nasty,especially when using a library based on interface {} when you are used to types documenting the code. At the same time you&#39;ll figure out soon enough you can&#39;t write compile time type safe abstractions in Go, especially when it involves containers.</p> <p>Go maintainers definitely belong to the first camp,as they throw in more API with interface {}.</p> <blockquote> <p>I&#39;ve heard arguments about this being a bad practices only from the community at large</p> </blockquote> <p>At the end of the day it only matters if you publish open-source libraries and can&#39;t take a criticism from random people on the internet. You should care only about what works for you and your team not what pundit X or Z has to say. Go maintainers don&#39;t have a problem using interface {} or reflection for convenience. Just know the cost of interface {}.</p></pre>hipone: <pre><p>Use of interface{} does not involve reflection in regular code, mostly type assertions.</p></pre>TheMerovius: <pre><blockquote> <p>Go maintainers definitely belong to the first camp,as they throw in more API with interface {}.</p> </blockquote> <p>Now, they come from C++. If you read the Google C++ style guide, you&#39;ll find that undeniable, it&#39;s essentially &#34;go without garbage collection&#34;.</p></pre>ar1819: <pre><p>Go maintainers tend to pick interface{} when there is no other options available (like Pool) or when they make sense (like Marshal family of functions). The former comes not powerful enough typesystem. The latter id just a label for <code>any</code>. </p></pre>hipone: <pre><p>Use of interface{} does not involve reflection in regular code, mostly type assertions.</p></pre>nstratos: <pre><p><a href="https://youtu.be/PAAkCSZUG1c?t=7m40s">interface{} says nothing.</a></p></pre>The_Sly_Marbo: <pre><p>I&#39;d say it&#39;s only acceptable where you want to handle <em>anything</em>. The only time I can think of where that is clearly true is with <code>Printf</code> -like functions and general purpose encoders like <code>json.Marshal</code>, where you want to be able to represent anything.</p></pre>binaryblade: <pre><p>It has a terrible code smell, but in the absence of generics, nessecary at times.</p></pre>quiI: <pre><p>As with most things in programming, there arent usually simple rules, just stuff that is generally good practice but there&#39;s always exceptions.</p> <p>It&#39;s important to understand the tradeoffs of using interface</p> <ul> <li>Losing type safety</li> <li>Less performant</li> <li>Your API becomes harder to use (i cant just look at the type signature)</li> </ul> <p>That said, because Go&#39;s type system isn&#39;t very rich it is sometimes needed to get around that. </p> <p>You&#39;ll find most of the time people criticising interface when it is patching up a lazy/bad design. You should <em>generally</em> prefer an implementation not using interface if it&#39;s reasonably possible.</p></pre>TheMerovius: <pre><p>IMHO: It&#39;s perfectly fine where it&#39;s useful, that is, mostly containers and encoding/decoding. I agree with static type-checks being very useful, but do not believe that you are going to get into any <em>actual</em> trouble in practice, if you are missing it in container-APIs. In practice, every container you use will have a clearly distinguished responsibility which determines the type stored in it and while doing <code>someHeap.Pop().(*myType)</code> might look somewhat ugly and inconvenient and could <em>in theory</em> panic, I don&#39;t believe it&#39;s in any sense a buzz-kill. And for en-/decoding, you already don&#39;t want to rely on any type info; so taking an <code>interface{}</code> very accurately expresses the type you are handling.</p> <p>Just… don&#39;t use it as a &#34;general value&#34;. Don&#39;t use it as <code>java.lang.Object</code>. Use it, where the loss of type-information either makes sense or is tolerably limited.</p></pre>

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

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