Right way to check for errors

polaris · · 378 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;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&#39;s common to see a lazy try-catch block at the top where there&#39;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&#39;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&#39;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&#39;m not following you.</p> <p>Can you receive the error, and not check it?</p> <p>If not, then I&#39;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&#39;s slightly better than C, but I&#39;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&#39;m taking the reigns of someone else&#39;s.</p> <p>I only like them if they&#39;re checked, and in that case they only add clutter over simple error values.</p></pre>tmornini: <pre><p>And when they&#39;re not checked, it&#39;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(&#34;ERROR 1&#34;, err) } if err = o.Do2(2); err != nil { log.Fatal(&#34;ERROR 2&#34;, err) } if err = o.Do3(3); err != nil { log.Fatal(&#34;ERROR 3&#34;, err) } log.Println(&#34;Ok&#34;) } </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(&#34;Ok&#34;) } </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(&#34;roomID&#34;), 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&#39;re being downvoted...</p></pre>the-varlog: <pre><p>Using panic (log.Fatal) isn&#39;t good idea, becouse it is much slower, then error.</p></pre>tmornini: <pre><p>Thanks, but assuming you&#39;re not using errors-as-flow-control -- which is a horrible practice -- then speed of error handling isn&#39;t very important.</p> <p>Additionally, I&#39;m very clear that your example doesn&#39;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&#39;t like that, don&#39;t insist, trust me.</p></pre>

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

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