<p>Hello Gophers,
last night I wrote my first program in Go, a "quote of the day" server.
Do you have any feedback for me on how I can write better Go code?
Are there any best practices I should look into?</p>
<p>My Code is available on <a href="https://github.com/cosmonawt/go-qotd" rel="nofollow">Github</a>.</p>
<p>Any feedback is highly appreciated. Thanks a lot :)</p>
<hr/>**评论:**<br/><br/>ohaiya: <pre><p>Nice.</p>
<p>A couple of things:</p>
<p>main.go, line 20</p>
<pre><code>r := rand.Intn(len(q) - 1)
</code></pre>
<p>If you look at the godoc for rand.Intn at <a href="https://golang.org/pkg/math/rand/#Intn" rel="nofollow">https://golang.org/pkg/math/rand/#Intn</a> the rand function returns a pseudo random value [0, n) or in other words, it can be 0 to (n-1), since n is not included in the set of values.</p>
<p>So, with your current approach, you'll never get the last QOTD in your csv file. You can change that line to:</p>
<pre><code>r := rand.Intn(len(q))
</code></pre>
<p>In relation to you general question about writing better code, Effective Go is worth reading:</p>
<p><a href="https://golang.org/doc/effective_go.html" rel="nofollow">https://golang.org/doc/effective_go.html</a></p></pre>evantreb0rn: <pre><p>Hey, thanks for the quick feedback!
That was actually done on purpose, since the script I supplied generates an empty line at the end of the file, which would then end up as an empty string in the array after slicing the file content.</p>
<p>You are right of course, in general this should not be necessary.</p></pre>OTkhsiw0LizM: <pre><p>You could use <code>log.Print</code> instead of <code>fmt.Println</code> in almost all cases. You could also load the whole file in memory on startup and reuse that instead of re-reading the file on every request.</p></pre>absdevops: <pre><p>Tiny thing, but from most code I've read - func main is usually at the top (also arranging your functions in order of execution is useful for people reading the code)</p></pre>tmpler: <pre><p>You really should use more meaningful variable names
for example <code>a := os.Args[1:]</code> would be better as something like
arguments, args or something.
And if I'm seeing this correctly: you want to get two arguments,
without but only pass one to the server function.
the</p></pre>evantreb0rn: <pre><p>I was actually under the impression, that Go code more often than not uses very short und undescriptive variable names (a, r, bs etc.).
Thanks for the feedback though, I agree very much with you.</p>
<p>As for your second point, the second argument gets not read by the main() function but rather randomQuote().
This is one thing where I would like more feedback for example?
Is it better to pass this argument through three functions while only needed in the last of them or is it better to access it directly where needed?</p></pre>tmpler: <pre><p>I would suggest to read this varibale inside your <code>main</code> function and pass it to your functions as needed. Because then you have all side effects (in this case, user input) only inside your <code>main</code> function and not overall in your code base</p></pre>evantreb0rn: <pre><p>Thanks!</p></pre>LimEJET: <pre><blockquote>
<p>I was actually under the impression, that Go code more often than not uses very short und undescriptive variable names (a, r, bs etc.).</p>
</blockquote>
<p>I see where you're coming from, but as far as I can tell, the go standard library usually has abbreviated variable names. It's not just random. </p>
<p>A good example is <a href="https://golang.org/src/strings/strings.go?s=22754:22786#L864" rel="nofollow"><code>strings.EqualFold</code></a>. Here, the first input is <code>s</code>, probably because it is a string. The next one is <code>t</code> since it's the letter after s. Fair enough.<br/>
Then, you grab the first runes and put them into <code>sr</code> and <code>tr</code> (so "s rune" and so on for the second one). They're still a bit too short, but they make sense in context.</p></pre>evantreb0rn: <pre><p>Thats what I was thinking off when I wrote the code. My variable names are also (heavily) abbreviated, but not randomly chosen.</p>
<p>I guess one has to find a middleground there?</p></pre>LimEJET: <pre><p>That's usually the problem, yes. I tend to go for half-abbreviations so that you can still understand what the variable contains when randomly stumbling on it, without it being overly long.</p></pre>
![](https://static.golangjob.cn/static/img/banner.png)