<p>I'm learning go and my code is full of this: </p>
<pre><code> if err != nil {
// something
}
</code></pre>
<p>Is that right? It seems like a lot of repetition.</p>
<hr/>**评论:**<br/><br/>robertmeta: <pre><p>Yes, that is fine. You check for errors, and then you handle them. </p></pre>thepciet: <pre><p>There are a lot of times where the reality is some code repetition is worth the result - in this case not having to deal with arguing over the other few ways to do it.</p></pre>pafortin: <pre><p>This was already asked here on reddit - <a href="https://www.reddit.com/r/golang/comments/4126jh/is_err_nil_the_best_idiom_for_error_handling/" rel="nofollow">https://www.reddit.com/r/golang/comments/4126jh/is_err_nil_the_best_idiom_for_error_handling/</a></p></pre>upboatact: <pre><p>there is also an official blog post about it <a href="https://blog.golang.org/error-handling-and-go" rel="nofollow">https://blog.golang.org/error-handling-and-go</a> and <a href="https://blog.golang.org/errors-are-values" rel="nofollow">https://blog.golang.org/errors-are-values</a></p></pre>mixedCase_: <pre><p>This is the Go way of handling errors.</p>
<p>It forces you to handle them at the right level so you know which pathways can lead to failure, and only bubble/ignore the error consciously.</p>
<p>And yes, this is contrary to the usual unchecked exceptions you see in other languages; where it's common to see a lazy try-catch block at the top where there's no graceful handling of failure and the developer might not even be aware of how his calls can fail.</p></pre>tmornini: <pre><p>It's also nearly identical to the way C did, and history is replete with examples of bad things happening when people forgot to check the errors.</p>
<p>Big Go fan, but the error handling is a weakness that I desperately hope will be corrected in the future.</p></pre>mixedCase_: <pre><blockquote>
<p>C did, and history is replete with examples of bad things happening when people forgot to check the errors.</p>
</blockquote>
<p>Which is why Go won't let you compile unless you explicitly ignore errors via calling the function as-is or not checking the variable receiving the error.</p></pre>tmornini: <pre><p>I'm not following you.</p>
<p>Can you receive the error, and not check it?</p>
<p>If not, then I'm a little happier. :-)</p></pre>mixedCase_: <pre><blockquote>
<p>Can you receive the error, and not check it?</p>
</blockquote>
<p>You can ignore it if you blackhole it (assign to <code>_</code> variable) or calling the function without assigning its return values to any variable.</p>
<p>If you do it though, you better have a good goddamned reason.</p></pre>tmornini: <pre><p>Yeah, that's slightly better than C, but I'd still far prefer exceptions.</p>
<p>Code Complete anyone?</p></pre>BoTuLoX: <pre><p>I prefer exceptions until I actually have to maintain the program or I'm taking the reigns of someone else's.</p>
<p>I only like them if they're checked, and in that case they only add clutter over simple error values.</p></pre>tmornini: <pre><p>And when they're not checked, it's always obvious and never a mystery.</p>
<p>Super unclear why you thing a captured exception is more clutter than an if.</p>
<p>I prefer the clear visual difference AND crashing to get-another-if statement and/or undefined behavior if someone misses the check.</p></pre>the-varlog: <pre><p>It is ok, when you code looks like:</p>
<pre><code>func example1() {
var (
o = Object{}
err error
)
if err = o.Do1(1); err != nil {
log.Fatal("ERROR 1", err)
}
if err = o.Do2(2); err != nil {
log.Fatal("ERROR 2", err)
}
if err = o.Do3(3); err != nil {
log.Fatal("ERROR 3", err)
}
log.Println("Ok")
}
</code></pre>
<p>Or the second way:</p>
<pre><code>func must(err error) {
if err != nil {
log.Fatal(err)
}
}
func example2() {
o := Object{}
must(o.Do1(1))
must(o.Do2(2))
must(o.Do3(3))
log.Println("Ok")
}
</code></pre>
<p><a href="https://play.golang.org/p/6N9MJ8G9jc" rel="nofollow">on play.golang</a></p></pre>fortytw2: <pre><p>this is <em>only</em> ok inside your <code>main()</code> function - never anywhere else</p></pre>the-varlog: <pre><p>log.Fatal is just for example, omg. For example, real part of my code:</p>
<pre><code>func Read(c *gin.Context) {
var (
room = Room.New()
roomID uint64
err error
)
if roomID, err = strconv.ParseUint(c.Param("roomID"), 10, 64); err != nil {
responses.BadRequest().Respond(c)
return
}
if err = Room.Find(roomID, room); err != nil {
responses.InternalServerError().Respond(c)
return
}
if err = room.WithTitleIDs(); err != nil {
responses.InternalServerError().Respond(c)
return
}
responses.OK(room).Respond(c)
}
</code></pre></pre>tmornini: <pre><p>This is fantastic, thanks.</p>
<p>So much better than littering your code with if/then/else statements!</p>
<p>No idea why you're being downvoted...</p></pre>the-varlog: <pre><p>Using panic (log.Fatal) isn't good idea, becouse it is much slower, then error.</p></pre>tmornini: <pre><p>Thanks, but assuming you're not using errors-as-flow-control -- which is a horrible practice -- then speed of error handling isn't very important.</p>
<p>Additionally, I'm very clear that your example doesn't need to be taken verbatim. :-)</p></pre>interactiv_: <pre><p>Welcome to go /s </p>
<p>this serves as a test to figure out whether that language is good for you ... or not.</p>
<p>IF you don't like that, don't insist, trust me.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传