<p>If it's not and sacrificing type safety, then why is it there? If it's there, why using it is considered bad.? Isn't it just like an "any" type in many languages (except there is a <code>nil</code> in Go).
I'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't make a single, general statement like <code>interface{} is acceptable</code> or <code>interface{} is bad</code>. It's a tool that can be used. It'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'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'll figure out soon enough you can'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'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'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'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'll find that undeniable, it's essentially "go without garbage collection".</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'd say it'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's always exceptions.</p>
<p>It'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's type system isn't very rich it is sometimes needed to get around that. </p>
<p>You'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's reasonably possible.</p></pre>TheMerovius: <pre><p>IMHO: It's perfectly fine where it'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't believe it's in any sense a buzz-kill. And for en-/decoding, you already don'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't use it as a "general value". Don'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
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传