[Question] "Packages Are Not Namespaces"?

polaris · · 556 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>In API projects that are split into multiple files, it&#39;s common to see the same package name declared in each file, <code>package main</code>. </p> <p>It&#39;s my understanding that if every file is in the same directory, <code>go</code> treats it as a one big file and you don&#39;t actually have to export anything. <a href="https://github.com/corylanou/tns-restful-json-api/tree/master/v9" rel="nofollow">Here is an example</a>. In this project, I&#39;m finding <code>main.go</code> difficult to reason about. Where does <code>NewRouter</code> come from? Confusingly enough, it&#39;s actually defined in <code>router.go</code>! But wait, <code>router.go</code> references the <code>routes</code> slice, which is defined in some other file. I couldn&#39;t have known that without going over every file looking for a variable declaration somewhere. </p> <p><strong>Is this repository exhibiting best practices?</strong></p> <p>I ask because I also see Go API examples that essentially use packages like you would a namespace and &#34;import&#34; their files (I&#39;ve also read that this is NOT correct). After building out a new service with all of it&#39;s routes, handlers, types, and interfaces in a single <code>main.go</code> file, I&#39;m very much looking forward to learning what the best path forward is.</p> <p><strong>Bonus Question</strong>: What would be the correct conventions to stick to if I&#39;d like to use a directory structure like below (and if it&#39;s totally incorrect, I&#39;m all open to alternatives)?</p> <p>---- $GOPATH/src/bitbucket.org/morty/projectB</p> <p>-------- main.go</p> <p>------------ Routes/</p> <p>------------ Interfaces/</p> <p>------------ Handlers/</p> <p>------------ Repos/</p> <p>------------ Services/</p> <p>------------ Tests/</p> <p>Thanks a ton! After working through the Tour, Bootcamp, and actually deploying something, I think this language is awesome. This is just tough to wrap one&#39;s head about. </p> <p><strong>What I&#39;ve read before asking for help</strong></p> <ul> <li><p><a href="https://github.com/alco/gostart#3-how-do-i-split-my-package-into-multiple-files" rel="nofollow">https://github.com/alco/gostart#3-how-do-i-split-my-package-into-multiple-files</a></p></li> <li><p><a href="http://www.goinggo.net/2014/03/exportedunexported-identifiers-in-go.html" rel="nofollow">http://www.goinggo.net/2014/03/exportedunexported-identifiers-in-go.html</a></p></li> <li><p><a href="http://www.golangbootcamp.com/book/methods#cid33" rel="nofollow">http://www.golangbootcamp.com/book/methods#cid33</a></p></li> </ul> <p><em>Edit</em>: Adding clarification</p> <p><em>Edit 2</em>: Despite the downvotes, I hope the great answers here help someone else as well. </p> <hr/>**评论:**<br/><br/>abcded1234234: <pre><p>I think for a small application putting everything into one package main (possibly across multiple files) is the best choice.</p> <p>For larger applications start with a single package main and then extract packages as necessary. However do not split code into packages by layers (like in your example). It is better to split by features (such as auth, users, shoppingcart, etc).</p> <p>A slightly related advice: use an editor (or IDE) that supports &#34;jump to definition&#34; functionality. Then questions like &#34;Where does New Router come from&#34; would be much easier to answer.</p></pre>joushou: <pre><p>Yes, packages should be split based on them being isolated, maybe even reusable functionality. If you instead split interleaved functionality as an attempt to group things, then you end up with a cyclic dependency mess.</p> <p>I would argue that the name of the file, router.go, gives away the presence of NewRouter. :)</p> <p>Jump to definition is nice, but I also very much enjoy not having it. It means that, if things aren&#39;t easy to navigate, people get frustrated and fix it, which is quite contrary to some languages known to be very jump-to and IDE heavy (usually Eclipse being the IDE, to give hints to the language).</p></pre>thewhitetulip: <pre><p>check <a href="http://github.com/thewhitetulip/web-dev-golang-anti-textbook" rel="nofollow">http://github.com/thewhitetulip/web-dev-golang-anti-textbook</a> and go through <a href="http://github.com/thewhitetulip/Tasks" rel="nofollow">http://github.com/thewhitetulip/Tasks</a> to understand the functionality of the application</p></pre>RickAndMorty_forever: <pre><p>Thanks for posting this! I like the writing style of the book, I&#39;m going to look over this during lunch. </p></pre>thewhitetulip: <pre><p>You are welcome! I am happy the book is helping :)</p></pre>drvd: <pre><p>In Go packages typically contain <em>all</em> code for some specific concept. So in a web application you would have maybe a <code>package user</code> for everything user-related and a <code>package blogpost</code> for everything dealing with a blog post. And <code>package blogpost</code> would contain the routing, the handler, the data model and the view model (or whatever MVXYZ-religion you are following).</p> <p>And of course each package has it&#39;s own test code in the <code>*_test.go</code> files.</p> <p>I hope this answers our &#34;Bonus Question&#34;. Go is different in this regards. As you can multiple types and functions etc. in one package it is much more natural to group by concept than the &#34;traditional&#34; (??) grouping by class and functionality used by Java, Ruby et al.</p></pre>RickAndMorty_forever: <pre><p>This makes sense, thank you! It looks like declaring a variable in one file of <code>packageA</code> and referencing it in a different file of <code>packageA</code> is completely legal, if not slightly hard to follow. Is this commonly practiced?</p></pre>

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

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