Package scoping is so hard to follow

agolangf · · 502 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>The past month I&#39;ve been learning Go, and I&#39;m really starting to feel comfortable with it and find pieces that are interesting and exciting (as initially it wasn&#39;t so). </p> <p>I&#39;ve been looking through Golang projects and one thing that stands out strongly that I find really difficult is how functions are scoped within a package in relation to files in that package. </p> <p>For example, in <code>package main</code>, you have <code>main.go</code> file that uses <code>someRandomFunc()</code>, and this function could be declared in any of the files in this package, such as in <code>api.go</code>, but the usage in <code>main.go</code> doesn&#39;t make this explicit where it comes from. </p> <p>The bias, or my experience of what I&#39;m used to, is doing something like this:</p> <p><code>index.js</code>:</p> <p><code>import { someRandomFunc } from &#39;./api&#39;</code></p> <p><code>api.js</code>:</p> <p><code>export function someRandomFunc () { ... }</code></p> <p>What I find so hard to follow is that when I am orientating myself to a new project, I&#39;ll start looking in <code>main.go</code> and see some use of functions, then I&#39;m asking myself, &#39;where was that declared?&#39; and have to grep the directory for it.</p> <p>I&#39;ve heard a lot about making things simple and clear in Go, but for me, this is complicated. </p> <p>I&#39;d be glad to hear more experienced Gopher&#39;s thoughts on this - perhaps it&#39;s not a problem for you and you can point out where I&#39;m approaching it incorrectly/poorly, or maybe you overcame this somehow. </p> <hr/>**评论:**<br/><br/>dlsniper: <pre><p>Also, if you use Chrome, check the SourceGraph extension for Chrome and Github: <a href="https://chrome.google.com/webstore/detail/sourcegraph-for-github/dgjhfomjieaadpoljlnidmbgkdffpack?hl=en" rel="nofollow">https://chrome.google.com/webstore/detail/sourcegraph-for-github/dgjhfomjieaadpoljlnidmbgkdffpack?hl=en</a></p></pre>shovelpost: <pre><p>With vim and vim-go it&#39;s just as easy as <code>gd</code> to quickly go to the definition of a function.</p></pre>seufert: <pre><p>Actually in most editors with their go support: Emacs, Sublime and Visual Studio Code and as mentioned by dlsniper Intellij.</p></pre>jaetteintemer: <pre><p>Is third party tooling then the only way to work through this? I guess after hearing so much about the philosophy of Go -- that things should be clear and simple -- I find the lack of language-level clarity in this surprising. </p></pre>itsmontoya: <pre><p>Almost every language has tooling. Some of the &#34;best&#34; languages have gained that status as a result of incredible tooling.</p></pre>hahainternet: <pre><blockquote> <p>I find the lack of language-level clarity in this surprising</p> </blockquote> <p>There&#39;s a number of reasons behind this, for a start, Go code is compiled to a single binary, not a series of .pyc files for example (yes I know about .o) and as a result the packages become actually one package. It would be awful to say &#34;import github.com/someurl from github.com/someurl/packagefile&#34;</p> <p>Next, while bare functions are completely acceptable, most functions should be attached to types and packages also named after the types or a subset. Instead of someRandomFunc it should potentially be Item.RandomFunc and the code can belong in item.go.</p> <p>These rules aren&#39;t universal, and it&#39;s really down to how you personally prefer things, but this is how I see it.</p></pre>jaetteintemer: <pre><p>Thanks for your thoughtful reply. In your example of <code>item.go</code>, do you mean that <code>RandomFunc</code> is a method on <code>Item</code>, or is it more like how there is <code>flag.Parse</code> ? </p></pre>exit-gate: <pre><blockquote> <p>I find the lack of language-level clarity in this surprising</p> </blockquote> <p>What does that statement mean? I feel like I&#39;m missing something here (you make vague claims, with no evidence of what you&#39;re talking about)</p></pre>globalgobble: <pre><p>What&#39;s the package for emacs ?</p></pre>i4k: <pre><p><a href="https://github.com/dominikh/go-mode.el" rel="nofollow">https://github.com/dominikh/go-mode.el</a></p></pre>jaetteintemer: <pre><p>Cool! that&#39;s helpful to know at least.. </p></pre>The_Sly_Marbo: <pre><p>Go&#39;s syntax also makes it really easy to search with grep. Find function <code>foo()</code> with <code>grep -n &#39;func foo&#39; *.go</code> and method <code>foo.bar()</code> with <code>grep -n &#39;\) bar&#39; *.go</code>.</p></pre>dlsniper: <pre><p>With IntelliJ you can pretty much follow both scopes and as well define different colors for them as well as notice when you are shadowing a variable.</p></pre>earthboundkid: <pre><p>This should not be a problem in well written code. In Go, files in the same package/directory share a namespace, but well written code should have very little in package main and most code in other packages. Treating directories as one package means you don&#39;t need to make files huge to satisfy your API. It may be that your package only exposes a few functions to the public but has an extensive internal logic. Because directories are one namespace, you can still arrange the internal code well. </p></pre>jaetteintemer: <pre><p>In line with what you&#39;re sharing here, are there best practices for where to place what is exported? Also, are you talking literally about the <code>/internal</code> directory?</p></pre>exit-gate: <pre><blockquote> <p>What I find so hard to follow is that when I am orientating myself to a new project, I&#39;ll start looking in main.go and see some use of functions, then I&#39;m asking myself, &#39;where was that declared?&#39; and have to grep the directory for it.</p> <p>I&#39;ve heard a lot about making things simple and clear in Go, but for me, this is complicated. </p> </blockquote> <p>I find this a bit strange... If things are in multiple files how else are you going to find things without grepping or using some other dedicated tool?</p> <p>Serious question: how do you go about finding things in the same file, and how is it different to finding in other files? I can&#39;t remember the last time I used an editor that didn&#39;t have some builtin indexing available to find symbols in the entire project or one that was incapable of searching through all files in the project.</p></pre>jaetteintemer: <pre><p>Well, I outlined in my first post how I&#39;m used to this from Node.. I see your point, too, though</p></pre>dinkumator: <pre><p>It won&#39;t work (easily) for unexported functions, but you can also run godoc locally to show all the package-level exported functions:</p> <pre><code>godoc -http=:6060 </code></pre> <p>Then add <code>?m=all</code> to the doc url to see unexported types/functions: <a href="http://localhost:6060/pkg/net/?m=all" rel="nofollow">http://localhost:6060/pkg/net/?m=all</a></p> <p>This won&#39;t work for <code>package main</code> without a modified godoc though. <a href="https://github.com/golang/go/issues/5727" rel="nofollow">CL here</a> if that&#39;s what you want...</p></pre>jaetteintemer: <pre><p>Awesome, thanks!</p></pre>i4k: <pre><p>If only what you want is the documentation of the func/const/var then you would like <code>go doc</code>.</p> <pre><code>go doc somepkg.SomeFunc </code></pre> <p>To look for unexported symbols:</p> <pre><code>go doc -u somefunc </code></pre></pre>thepciet: <pre><p>I struggle with this too. Organizing symbols is a significant task in Go for anything other than very small projects.</p></pre>icholy: <pre><p>it really isn&#39;t</p></pre>

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

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