[Show] file_finder - First Go project. Would love feedback.

blov · · 560 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<h4><a href="https://github.com/cwramsey/file_finder">file_finder</a></h4> <p>I just finished writing a (very) short tool in Go to help get some of the basics in the language.</p> <p>It&#39;s a simple cli tool that (can recursively) find files matching a string.</p> <p>It&#39;s a whopping 74 lines of code, including plenty of spacing for readability.</p> <p>I&#39;d love to hear what&#39;s absolutely terrible and what could be done more <code>Go-like</code>. The logic isn&#39;t perfect, but for a little tool I threw together to grasp the basics of the language, it&#39;ll do for now. That said, I&#39;m mainly looking for your thoughts on how I can write better Go with this.</p> <p>For example, I&#39;ve read something about <code>File.ReadDir</code> might be better than <code>ioutil.ReadDir</code>?</p> <p>Anyway, thanks in advance for taking a peek!</p> <hr/>**评论:**<br/><br/>nstratos: <pre><p>First of all, welcome to Go and it&#39;s community. I hope you will enjoy writing the language, keep learning and having fun!</p> <p>As you have already mentioned, this is a little program so most of the things I am going to mention are nitpicks. Nevertheless I hope they will help you learn more about the language and it&#39;s philosophy. </p> <ul> <li>Prefer <a href="https://talks.golang.org/2014/names.slide#7">shorter names</a> for your local variables. </li> <li>While this is not exactly what the proverb means: &#34;<a href="https://youtu.be/PAAkCSZUG1c?t=6m25s">Make the zero value useful</a>&#34; is what comes to mind. </li> </ul> <p>You can delete those 3 lines:</p> <pre><code>if *directory == &#34;&#34; { *directory = &#34;./&#34; } </code></pre> <p>if you use a default value as the second argument of <code>flag.String</code>:</p> <pre><code>directory := flag.String(&#34;dir&#34;, &#34;.&#34;, &#34;Directory you&#39;d like to search in. ex: /var/www/&#34;) </code></pre> <ul> <li><p>While <a href="https://github.com/golang/lint">golint</a> will not complain, it&#39;s good if you have a <a href="http://blog.golang.org/godoc-documenting-go-code">doc comment</a> describing your command above <code>package main</code> so that if someone stumbles upon your program in <a href="https://godoc.org/">GoDoc</a>, they can learn what it is about.</p></li> <li><p>Try to keep your program portable. Lines like <code>directory+&#34;/&#34;+thisItem.Name()</code> can be problematic. What if you try to run this on windows that uses &#34;\&#34; as a path separator? It&#39;s a good idea to use the <a href="https://golang.org/pkg/path/filepath/">filepath package</a> for those cases and do something like: <code>filepath.Join(directory, thisItem.Name())</code>which will ensure portability among the platforms that <a href="https://golang.org/doc/install/source#environment">Go supports</a>.</p></li> <li><p>It is a good practice to extract as much of your logic as you can, in a separate package. The functions <code>search</code> and <code>searchRecursively</code> are good candidates.</p></li> <li><p>Extracting your logic in a separate package has increased benefits like making your code <em>reusable</em> and <em>easier to maintain</em> and also allows you to write <a href="https://golang.org/pkg/testing/">unit tests, benchmarks and examples</a> easier. Good reads: <a href="https://golang.org/doc/code.html">How to Write Go Code</a>, <a href="https://golang.org/doc/effective_go.html">Effective Go</a>, <a href="https://github.com/golang/go/wiki/TableDrivenTests">Table Driven Tests</a>, <a href="https://blog.golang.org/cover">The cover story</a></p></li> <li><p>Something important is that you should prefer to use interfaces (like <code>io.Reader</code>) as arguments in your functions. Think about a function that takes <code>path string</code> as argument and then inside it opens the file belonging to that path in order to perform some kind of logic on that file. You need to ask yourself: &#34;Is it really the responsibility of that function to open the file?&#34; In your case, the answer is probably no as the purpose of your functions is to search, not open files. Instead you could let <code>main</code> (or another function) handle the opening/reading and just keep the core search logic in the search functions. This will also allow you to:</p> <ul> <li>write unit tests for you function logic much easier. </li> <li>make your functions more powerful and generic.</li> </ul></li> <li><p>It&#39;s always good to think about error handling. Your functions could possibly return an <code>error</code> as a second argument. For example, what if <code>os.Chdir(directory)</code> fails? Sure it is unlikely but errors are a big part of programming and you should take good care of them. Go has a slightly different philosophy when it comes to errors than other languages. Good reads: <a href="http://blog.golang.org/error-handling-and-go">Error handling and Go</a>, <a href="https://blog.golang.org/errors-are-values">Errors are values</a></p></li> <li><p>Truly a technicality but <a href="http://tldp.org/LDP/abs/html/exitcodes.html">traditionally</a> exit code 2 is used when the user uses wrong options. You can see that a lot in Go standard library code like in <a href="https://github.com/golang/go/blob/master/src/cmd/gofmt/gofmt.go#L55-L59">gofmt</a>.</p></li> <li><p>You can also use a <code>.gitignore</code> file so that you can ignore the <code>file_finder</code> binary file and not commit it in your repository. You can distribute your binary using <a href="https://help.github.com/articles/creating-releases/">GitHub releases</a> and Go developers can always use <code>go get</code>.</p></li> <li><p>Have a License for your public repository.</p></li> </ul> <p>There might be other things you can improve but those are the ones that I noticed. Happy hacking!</p></pre>shadowycoder: <pre><p>Hey, thanks! This is exactly the kind of feedback I was looking for. I really appreciate you taking the time to write this out. <a href="https://media.giphy.com/media/MpiWetOCN5Sx2/giphy.gif">+1</a></p></pre>9eb5: <pre><p>Why not just use filepath.Walk instead of recursing into directories manually?</p></pre>shadowycoder: <pre><p>Only because I didn&#39;t know it existed yet. Thanks for the tip!</p></pre>

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

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