What are the three features of Go you dislike the most?

xuanbao · · 1005 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Mine are:</p> <ol> <li>Fallthrough</li> <li>The empty interface </li> <li>The uint63 and int63 functions in math.Rand - unbelievably ugly!</li> </ol> <hr/>**评论:**<br/><br/>YEPHENAS: <pre><p>The empty interface is not a separate feature. It&#39;s just a regular interface. It could not be removed without removing interfaces as a whole or without adding special logic.</p></pre>bitmadness: <pre><p>That&#39;s true. What I was really trying to get at is the lack of type safety associated with using empty interfaces. Coming from a functional background (Haskell), it just seems weird to throw information away.</p></pre>TheMerovius: <pre><p>As repeated everywhere: <code>interface{}</code> is perfectly type safe, it just moves the type checks to runtime, which is literally it&#39;s point.</p></pre>barsonme: <pre><p>You are correct, however I think people just mean compile-time type safety when they say it like OP did. </p> <p>Sure, the runtime will catch it, but that might be two months down the road when your web app crashes. </p></pre>bitmadness: <pre><p>Yes, this is what I meant. A Haskeller would laugh if you said &#34;caught at runtime&#34; and meant &#34;safe&#34;.</p></pre>mm256: <pre><p>You should try (void*) pointers in C. They completely throw away the type safety and compiler check.</p></pre>metamatic: <pre><ol> <li>Two different assignment operators, and you have to use both and remember which to use when.</li> <li>No parametric polymorphism.</li> <li>The inadequacy of the standard logging library, and its silly non-standard date format.</li> </ol></pre>tmornini: <pre><blockquote> <p>silly non-standard date format</p> </blockquote> <p>:-)</p></pre>amorphatist: <pre><p>(A): My main gripe: you can&#39;t currently refer lexically to a type. I end up doing horrible stuff like this:</p> <p>var TypeBaseNode = reflect.TypeOf((*BaseNode)(nil)).Elem()</p> <p>if typ == TypeBaseNode { doSomething()</p> <p>This is obviously silly. You should be able to do something like:</p> <p>if typ == type(BaseNode) // or if typ == BaseNode.type</p> <p>Somebody opened an issue: <a href="https://github.com/golang/go/issues/7112" rel="nofollow">https://github.com/golang/go/issues/7112</a></p> <p>(B) Not so much a language issue as a stdlib gripe: the sql package doesn&#39;t allow you to get the types of returned columns (only the column names). This kinda precludes using the package to build generic database tools.</p> <p>(C) I&#39;ll think of something...</p></pre>natefinch: <pre><p>Does a type assertion or type switch not work for your case?</p> <pre><code>if _, ok := type.(BaseNode); ok { </code></pre> <p>or </p> <pre><code>switch typ.(type) { case BaseNode: </code></pre> <p>?</p></pre>gohacker: <pre><p>Sorting. You have to have a type and three (!) methods to do the sorting. Hopefully this will be fixed (<a href="https://github.com/golang/go/issues/16721" rel="nofollow">issue 16721</a>).</p></pre>znpy: <pre><p>The compiler whining about imports not used and/or variables declared but not used.</p> <p>I would really like to be able to disable such features when I am prototyping, because most of the time it means that I have to do <strong>more</strong> work.</p> <p>It really gets in the way when I am changing a little something and have to waste time fixing imports and commenting stuff.</p></pre>captncraig: <pre><p>A no-nag flag would be cool. Not sure how to discourage its use though. </p></pre>znpy: <pre><p>it might only work when doing <code>go run &lt;something&gt;</code> but not when running <code>go install &lt;something&gt;</code>.</p></pre>TheMerovius: <pre><p><code>recover</code>… don&#39;t think there are any others.</p> <p>Also, there is no uint63 in <code>math/rand</code>, which wouldn&#39;t make any sense. Just <code>int63</code>, which has it&#39;s good reasons. It&#39;s a bit surprising that there is no <code>Uint64()</code>, though.</p></pre>bitmadness: <pre><p>Why does int63 make any sense?</p></pre>TheMerovius: <pre><p>Because the sign bit has some possibly undesirable consequences for the distribution. For example it&#39;ll have a negative bias (however slight that may be). And if you are really sure you want it, you can always generate a uint64 and cast that to int64.</p> <p>I am not an author of go, so I don&#39;t know why this particular choice was made, but I always assumed it&#39;ll be something along those lines.</p></pre>metakeule: <pre><p>Talking about Go - the project rather than Go - the language:</p> <ol> <li><p>the way package import and management problems where postponed, which led to incompatibilities and special cases like &#34;internal&#34; and &#34;vendor&#34; </p></li> <li><p>missing strategy for standard-library (parts where phased out, parts where supported, parts could not be improved due to compatibility promise)</p></li> <li><p>missing reusable abstractions around goroutines and channels</p></li> </ol></pre>agnsaft: <pre><p>int63? What is the use case for int63 and uint63?</p> <p>Personally, there is not much I dislike. Can live with most of the common complaints. The only thing that annoys me slightly on a day to day basis is the &#34;for range&#34; syntax for some reason. Not sure why, but maybe its because it feels more verbose than the rest of the language.</p></pre>xiegeo: <pre><ol> <li><p>select, or how hard it is to get select right. Deceptively simple, but hard to actually understand and test.</p></li> <li><p>range, only work for buildins, should also take an interface.</p></li> <li><p>chan&#39;s edge cases: send on a closed chan panics, and send on a chan with no receiver blocks. So there is no simple way to close a chan preemptively from the receiver size.</p></li> </ol> <p>And a missing feature, separate types for nil-able and non-nil-able pointers. This moves nil pointer exception from a run time error to compile time type error. Also removes the need for defensive nil checks when unnecessary.</p></pre>md2perpe: <pre><p>Not really a feature but something that I&#39;ve encountered:</p> <p>If type t implements interface I, then type []t does <em>not</em> implement []I.</p></pre>jjt: <pre><p>Named returns can be a source of bugs in longer functions and I could do without them in the language.</p></pre>brokenprogram: <pre><p>The empty interface would be the first on my list. It wouldn&#39;t that bad if we would have variant types as well. Using the empty interface should be the last resort(i.e. if you can&#39;t use variants). go/ast is a good example of how ugly it is.</p></pre>barsonme: <pre><ol> <li><p>Type rigidity. (However, I also like this.) For example: </p> <p>type foo byte f := foo(1) b := []byte{byte(f)}</p></li> </ol> <p>Sometimes I wish I could remove that last ugly conversation from type foo to type byte. </p> <ol> <li><p>How variadic arguments work. I know <em>why</em> it is the way it is, of course, but sometimes I dislike having to manually allocate a new slice of T. For example:</p> <p>// func Query(string, ...interface{}) query := &#34;SELECT * FROM...&#34; foo := &#34;some_id&#34; ids := []int{1,2,3,4,5} Query(query, foo, ids...) // oops, gotta make a new slice of interfaces</p></li> </ol> <p>On the other hand, AFAIK the only way to do this is how Go currently does it—the variadic args are actually a slice—and I don&#39;t want the language performing potentially large allocations without informing me. So, like #1, I see it both ways. </p> <ol> <li>No &#34;read only&#34; variables. (<code>const</code> isn&#39;t exactly what I&#39;m talking about.) Sometimes you can get better performance and/or it&#39;s more logical for a package to have a global variable like a map or array (e.g., a static lookup table). However, all it takes is one 2 AM programming session to accidentally assign to it and mess everything up. Plus, the compiler could possibly do more if it knew the program was contractually guaranteed never to modify the variable after a certain time (for instance, outside of init). </li> </ol></pre>libmn: <pre><ol> <li><p>Ugly syntax (compared to Nim).</p></li> <li><p>Missing boilerplate-reducing features (compared to Nim), especially lack of exception handling (without which your code can be 4x the length when you just want default &#34;print error message and fail behavior&#34;).</p></li> <li><p>Lack of secure and coherent package management (compared to pip, npm, nimble, cabal, etc, etc, etc).</p></li> </ol></pre>TheMerovius: <pre><p>Neither of those three things are features (and of course, it goes without saying, &#34;it&#39;s not Nim&#34; isn&#39;t a valid criticism).</p></pre>commentzorro: <pre><p>While the parent&#39;s post does seem a bit heavy handed, I do appreciate the concrete comparison for subjective items like, &#34;ugly syntax.&#34; I don&#39;t consider Go to have an ugly syntax but with that qualifier I do get when the poster means. Go and Nim are cosmetically quite different. If you like meaningful spaces and no braces then you&#39;re going to like Nim&#39;s syntax better. </p> <p>I disagree on syntax not being a feature though. Syntax is one of the most important features of any programming language. You don&#39;t pick a language based on syntax, you rule out a language based on syntax. Don&#39;t believe me? Take a look at J. Extremely powerful and concise. But how many people have looked at it and left it sitting there solely because of its syntax.</p></pre>

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

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