TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Discussion: Reduce error handling boilerplate in Golang using '?'

48 点作者 omani4 个月前

19 条评论

floating-io4 个月前
The biggest issue I have with this proposal is that reading the code in naïve fashion comes up with the wrong answer for me; YMMV. The proposed form--<p><pre><code> foo ? { bar } </code></pre> Reads naturally to me as &quot;If foo then bar&quot;, when it&#x27;s actually &quot;If foo&#x27;s error return exists then bar&quot;. I would suggest a different operator character, because this one reads wrongly IMO.<p>Maybe it&#x27;s just because I originally come from C, where `foo ? bar : baz` meant &quot;if foo then bar else baz&quot;, but the fact remains...
评论 #42855527 未加载
评论 #42854618 未加载
评论 #42858498 未加载
评论 #42854426 未加载
评论 #42854313 未加载
评论 #42864658 未加载
teeray4 个月前
I feel like error handling in Go is divided between people who have been using the language for a long time, and those who are new to it. If you&#x27;re used to exceptions, and languages with some kind of &#x27;?&#x27; operator, typing `if err != nil` all the time is probably excruciating. They seem to be the most vocal in the survey about wanting beloved error handling features from their favorite languages.<p>Once you&#x27;ve been using the language for awhile, you begin to dislike the elaborate system of rugs other languages have to sweep errors under. Errors in Go are right there, in your face, and undeniable that the operation you are doing can be faulty somehow. With good error wrapping, you can trace down exactly which of these `if err != nil` blocks generated the error <i>without a stack trace</i>. If it bothers you that much, you can always make a snippet &#x2F; macro for it in your editor.
评论 #42854035 未加载
评论 #42854072 未加载
评论 #42853848 未加载
评论 #42853890 未加载
评论 #42853932 未加载
评论 #42854479 未加载
评论 #42853818 未加载
评论 #42854501 未加载
theamk4 个月前
It saddens me tbat the default error handler is &quot;return err&quot;, as opposed to something that appends context&#x2F;stack trace.<p>We&#x27;ve converted a few scripts and webapps from Python to Go, and if one does default handling (&quot;return err&quot;) the error logs became significantly less useful, compared to exception backtraces. Yes, there are ways around it, but most tutorials don&#x27;t show them.
评论 #42876442 未加载
sigmonsays4 个月前
I vote no on this proposal.<p>Go error handling should remain simple, like the language.<p>These are all tools, just pick the one you like and stop trying to make them like others.
评论 #42854474 未加载
评论 #42854497 未加载
评论 #42854678 未加载
RedNifre4 个月前
(I&#x27;m not a Go programmer)<p>I find this a bit odd. Isn&#x27;t the idea of the primitive error handling that it is obvious and easy, as in &quot;functions can return multiple results, a popular pattern is to return the good result and the error as two separate nullable values of which exactly one will be not null, so you can check if err == nil.&quot;?<p>If you go with fancy error handling anyway, how is this &#x27;?&#x27; better than returning a Result and do something like foo().getOr { return fmt.Errorf(&quot;Tja: %v&quot;, err) }
评论 #42853892 未加载
cratermoon4 个月前
This is from Ian Lance Taylor, a major figure in the development of Go. Taylor was instrumental in bringing generics to the language, this proposal is worth taking seriously.
评论 #42853968 未加载
827a4 个月前
I overall like it and would prefer a world where Go had this spec implemented versus did not.<p>Criticism:<p>&gt; Within the block a new variable err is implicitly declared, possibly shadowing other variables named err<p>Shadowing here is strange, and I would prefer a design where it did not shadow other variables named err, but rather threw a compiler error concerning the re-declaration of a variable. That would effectively mean that you can&#x27;t mix-and-match this syntax with old error-handling inside one function, because code like this would fail to compile:<p><pre><code> func Test() { user, err := GetUser(&quot;12345&quot;) if err != nil { panic(err) } EmailUser(user) ? { panic(err) } } </code></pre> I&#x27;m fearful the shadowing will be confusing, because one might try to reference that shadowed error within the block in (rare) situations where you need to return the synthesis of two error values, and you&#x27;ll need to know the trivia of: `err` is a special name, I shouldn&#x27;t name that shadowed variable `err`, let me name it `err2`. Granted: throwing a compiler error would also disallow this and force you to name the first variable `err2`; but at least the compiler is telling you the problem, rather than relying on your knowledge of new trivia.
评论 #42855099 未加载
zimbatm4 个月前
This change would mark a turn in the language&#x27;s evolution, as it would be the first implicit variable to be added to the language.<p>I&#x27;m not going to invoke the slippery slope argument, but what distinguishes Go from the pack is how explicit it is. It can make it more tedious to write, but also much easier to follow as a reader.
评论 #42854615 未加载
评论 #42854601 未加载
vrnvu4 个月前
Unfortunately, every software project will eventually reach a point of maturity where more and more features are added simply for the sake of adding them.<p>&quot;The goal of this proposal is to introduce a new syntax that reduces the amount of code required to check errors in the normal case, without obscuring flow of control.&quot;<p>The key is &quot;check errors in the normal case&quot;.<p>When the core principles of Go have always been simplicity, flexibility, and having one way of doing things, this feels completely like a step in the opposite direction. We will have syntax sugar for &quot;normal cases&quot; while still relying on the `if err != nil` block for everything else. It’s similar to how we now have both `iterators` and `for loops` as constructions for loops.
评论 #42854732 未加载
jchw4 个月前
My knee jerk reaction is that introducing even more ways to write the same thing is going to slowly bloat the language, but Go does it infrequently enough that it doesn&#x27;t seem like it&#x27;s going to become a huge problem. I think I could get used to this syntax.<p>&gt; Disadvantage 4: No other block in Go is optional. The semicolon insertion rule, and the fact that a block is permitted where a statement is permitted, means that inserting or removing a newline can convert one valid Go program into another. As far as I know, that is not true today.<p>Yeah, this seems like a big problem to me, personally. Go has a fair number of lingering foot guns but this is one too far IMO. I think the no-block case should require something else to follow it, perhaps the return keyword. That&#x27;d also help prevent it from being as easily missed...
thiht4 个月前
I really hate that a bare ? makes us lose some info on code coverage. If you only test the happy path, the line is counted as covered. Making the return explicit at least makes it obvious when a line is uncovered.<p>But my biggest beef is the implicit variable declaration, I can’t stand it. That’s just lazy, bad design.<p>That’s not a great proposal overall, and I suspect if the same proposal had been made by someone else outside of the Go core team, we would have not heard of it.<p>I hope it gets rejected.
high_na_euv4 个月前
It is crazy that error handling is one of the most important things, yet even modern languages suck at it.<p>In my opinion everything should return type like MayFail&lt;T&gt;, Result&lt;T&gt;
jasonthorsness4 个月前
The proposal confuses shadowing of err, which is mostly irrelevant anyway but at least you can see it today. It also makes breakpoints or inserting log statements etc. more difficult without reformatting code. And lastly, it teases the ternary conditional operator that Go lacks, constantly reminding me of this. So IMO I would use a different language rather than adopt this.
rigelbm4 个月前
Error handling is really not an issue that needs fixing in Golang. That being said, I wish Golang had an assert key word as a shortcut to &quot;if cond { panic }&quot;. A lot of those &quot;if err != nil&quot; in the wild should really just be assertions.
评论 #42854226 未加载
TriangleEdge4 个月前
Seems like the author assumes that only one error is returned. What if I want to return []error? What happens if my return objects are out of the normal order? Like F() (int, error, int) {...}.<p>The proposal is nice, but a bit shallow.
评论 #42854077 未加载
evanmoran4 个月前
If I may make a suggestion to @ianlancetaylor, I think using the ? for error checking is a fantastic idea, but I think a couple small changes would make this absolutely a game changer and even more Go-like:<p>To demonstrate my tweak to your idea, imagine this example code:<p>r, err := SomeFunction() if err != nil { return fmt.Errorf(&quot;something 1 failed: %v&quot;, err) }<p>r2, err := SomeFunction2() if err != nil { return fmt.Errorf(&quot;something 2 failed: %v&quot;, err) }<p>r3, err := SomeFunction3() if err != nil { return fmt.Errorf(&quot;something 3 failed: %v&quot;, err) }<p>In the current proposal it would turn into this:<p>r := SomeFunction() ? { return fmt.Errorf(&quot;something 1 failed: %v&quot;, err) }<p>r2 := SomeFunction2() ? { return fmt.Errorf(&quot;something 2 failed: %v&quot;, err) }<p>r3 := SomeFunction3() ? { return fmt.Errorf(&quot;something 3 failed: %v&quot;, err) }<p>My first suggestion is to keep `err` variables visible. It ends up being not much longer, but it is <i>much</i> more readable and Go-like:<p>r, err := SomeFunction() ? { return fmt.Errorf(&quot;something 1 failed: %v&quot;, err) }<p>r2, err := SomeFunction2() ? { return fmt.Errorf(&quot;something 2 failed: %v&quot;, err) }<p>r3, err := SomeFunction3() ? { return fmt.Errorf(&quot;something 3 failed: %v&quot;, err) }<p>My second suggestion is to require ? to always have a block, and also allow them to &quot;chain&quot; so only the last statement needs a block:<p>r, err := SomeFunction() ? r2, err := SomeFunction2() ? r3, err := SomeFunction3() ? { return fmt.Errorf(&quot;something 1, 2 or 3 failed: %v&quot;, err) }<p>As you can see this is <i>much</i> shorter! Having the block is <i>always</i> required at the end of the &quot;chain&quot; of question mark statements is more consistent with how `if` statements require a block currently. It also makes the `return err` flow also always visible (no return magic). It also also has a huge advantage of it being much harder to miss a question mark syntactically. as a question mark without a block would be a syntax error.<p>For example, this is an error:<p>r, err := SomeFunction() ? &#x2F;&#x2F; &lt;-- compile error: missing block after ?<p>And also this is an error:<p>r, err := SomeFunction() ? r2, err := SomeFunction2() &#x2F;&#x2F; &lt;-- compile error: missing block after ? r3, err := SomeFunction3() ? { return fmt.Errorf(&quot;something 1, 2 or 3 failed: %v&quot;, err) }<p>Thanks for listening! Curious what folks think.
qaq4 个月前
honestly with copilot and friends this is not really an issue
reactordev4 个月前
This breaks go&#x27;s readability and explicit nature. No thanks. The author doesn&#x27;t understand the implications of the proposal. What if the args are in a different order returned? &quot;<i>foo, error</i>&quot; or &quot;<i>error, *foo</i>&quot; ? - I&#x27;ve seen many permutations of this. Being explicit about error handling is actually <i>a good thing</i>.
评论 #42854673 未加载
pphysch4 个月前
5 years ago I would be more sympathetic to this proposal.<p>But now we have LLM copilots, so writing boilerplate in any language is dramatically more optional.<p>And I don&#x27;t see this proposal significantly improving readability of the code.
评论 #42864899 未加载