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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

Declined Proposal: A built-in Go error check function, “try”

474 点作者 robfig将近 6 年前

32 条评论

wybiral将近 6 年前
This hits at something fundamental about Go, which is what I like the most about it...<p>It&#x27;s a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you&#x27;re forced to carry them up the chain.<p>Do I particularly <i>like</i> managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects.<p>The same goes with the Go ecosystem and tools. You might not like how gofmt forces your code or the documentation conventions used by golint but the fact that we all use the same convention and documentation is awesome and it&#x27;s what allows things like godoc.org. I think the proverb is &quot;gofmt&#x27;s style is no one&#x27;s favorite, yet gofmt is everyone&#x27;s favorite&quot;.<p>And things like the lack of abstractions and generics are what create a community that&#x27;s less reliant on dependencies. &quot;A little copying is better than a little dependency&quot; and you can see it in stark contrast to something like the JS community with its require(&#x27;left-pad&#x27;) NPM ecosystem.<p>So, yeah, I like that they didn&#x27;t fragment the community around something as arbitrary as this. And I get that some people won&#x27;t like it, just as they don&#x27;t like the lack of generics, but there is strength in some of these approaches that isn&#x27;t immediately obvious.
评论 #20455300 未加载
评论 #20455282 未加载
评论 #20455392 未加载
评论 #20457126 未加载
评论 #20455736 未加载
评论 #20456008 未加载
评论 #20455422 未加载
评论 #20455441 未加载
评论 #20456876 未加载
评论 #20472128 未加载
评论 #20470384 未加载
评论 #20455904 未加载
jph将近 6 年前
Kudos to the Go team for their process on this. IMHO it&#x27;s worth reading Russ Cox&#x27;s explanation of the problem area, including examples, and comparisons to other languages e.g. Rust and Swift.<p><a href="https:&#x2F;&#x2F;go.googlesource.com&#x2F;proposal&#x2F;+&#x2F;master&#x2F;design&#x2F;go2draft-error-handling-overview.md" rel="nofollow">https:&#x2F;&#x2F;go.googlesource.com&#x2F;proposal&#x2F;+&#x2F;master&#x2F;design&#x2F;go2draf...</a>
评论 #20455120 未加载
pcwalton将近 6 年前
I suspected this was coming, and it&#x27;s unfortunate. If Go had implemented try, then in a year everyone would be happy using it and the controversy would have died down. I&#x27;ve seen this happen before.<p>Unfortunately, the community that has sprung up around Go is more or less opposed to new language features on principle.
评论 #20455579 未加载
评论 #20455641 未加载
评论 #20455757 未加载
unixsheikh将近 6 年前
This is great news.<p>I really like how errors are handled in Go and I hated this proposal.<p>The current implementation forces you to constantly think about errors at each single point and it is extremely good at standing out. This is something very valuable, not something that requires or needs to be hidden behind syntactic sugar. It improves the readability of the code and the quality of the software.<p>If it ain&#x27;t broke, don&#x27;t fix it.
评论 #20455451 未加载
评论 #20455510 未加载
curtis将近 6 年前
A lot of Go programmers didn&#x27;t like this proposal at all. I&#x27;d like to think this is just because they didn&#x27;t think it was good enough. However, it seems that many, many Go programmers didn&#x27;t like it because they think Go error handling is just fine the way it is.
评论 #20455259 未加载
评论 #20455276 未加载
评论 #20455417 未加载
rbtprograms将近 6 年前
Good on the Go Team listening to the community, I definitely saw more people against this feature than for it.<p>I hope they take another stab at improving error handling. I like Go a lot and do think error handling is one place it could use improvements.
评论 #20455159 未加载
评论 #20455167 未加载
评论 #20455170 未加载
评论 #20455218 未加载
minieggs将近 6 年前
Perfect timing. Started mucking around with the Go compiler recently to implement my own error handling.<p><a href="https:&#x2F;&#x2F;pbs.twimg.com&#x2F;media&#x2F;D_ojiEqUYAAhmrH.png" rel="nofollow">https:&#x2F;&#x2F;pbs.twimg.com&#x2F;media&#x2F;D_ojiEqUYAAhmrH.png</a><p>edit: s&#x2F;%s&#x2F;%d&#x2F; but you get it.
poweroftrue将近 6 年前
Just try writing three Go programs with error handling, then, try other languages!<p>I was pissed at first. However, now I cannot code in any language without overusing try and being scared of each line.<p>Using Go&#x27;s error handling is actually making your code smarter, I mean, you don&#x27;t want your code to break with a weird message because of something stupid.<p>The simplest example is adding a default-path whenever I&#x27;m reading a file, Go&#x27;s error handling reminds me of what to do if this file doesn&#x27;t exist! Or cannot read etc.<p>Don&#x27;t take my word for it, Go ;) try it.
评论 #20455990 未加载
评论 #20455942 未加载
vegancap将近 6 年前
Quite rightly, too! It&#x27;s annoying for beginners, but you quickly see the utility in the if err != nil {} approach, or &#x27;sad path&#x27; approach after a few years of using Go in production. You learn to love it! To be honest, there&#x27;s very little I&#x27;d add to the Go language, if anything. It&#x27;s very unique that most Go developers share that view of a language. With Javascript, for example, I can&#x27;t wait for &#x27;new stuff&#x27;, I think that&#x27;s sometimes symptomatic of a broader dissatisfaction.
评论 #20461275 未加载
voidfunc将近 6 年前
It&#x27;s rather disappointing that Go has managed to bungle error handling so badly in a language only a handful of years old.
评论 #20457856 未加载
alexbanks将近 6 年前
This thread is rife with &quot;Go should have Try because I want Try&quot; that also seem to be made by developers that do not write Go. It seems confusing to me that voices generally involved from Go are so demanding of its maintainers.<p>Curious, are there full-time (or at least Primary) Go developers that are upset by the lack of Try?
评论 #20456303 未加载
评论 #20456970 未加载
评论 #20458035 未加载
评论 #20459623 未加载
cwojno将近 6 年前
Personally, I feel that the motivation for the issue is one of convenience. The most common use case is changing the flow control in the event of an error to return from the current stack. I&#x27;m not a fan of defining an error handler. This seems far too intrusive and cumbersome and a bridge too far.<p>GoLand gets around this somewhat by adding in the Live Template of &quot;err&quot; being a macro expansion for the if err != nil { return }. However, it still adds those 3 lines below each requisite call.<p>If they added a new keyword that took the place of this macro, would that be too intrusive? Clearly, this only works if you have named return values.<p>It would be nice if there was a bash&#x2F;Ruby-like chaining, such as:<p><pre><code> var1, var2, var3, err := call1(args) &amp;&amp; var4, var5, var6, err := call2(args) &amp;&amp; ... and more calls and so on ... return callN(args) </code></pre> Where &quot;&amp;&amp;&quot; would perform the if err != nil { return } in-line. Should the first call return a non-nil error as the last argument, flow would be returned to the caller. If not, the flow continues as normal.<p>This could even be extended in the case of function chaining:<p><pre><code> return call3( call2( call1(args) &amp;&amp; ) &amp;&amp; ) </code></pre> The downside of using &amp;&amp; is that it&#x27;s overloading the &amp;&amp; and may cause some compiler&#x2F;developer confusion. This was just an example based on a familiar use case (bash); another token can be used.<p>Rasky suggested something like this based on another proposal in the thread, but using &quot;?&quot; instead.<p>Another way to approach this might be an overlay language analogous to Kotlin. There could be a Go dialect that compiled into Go that provided this feature. Or, possibly an optional &quot;plugin&quot; for go&#x27;s compiler that added an intermediate transformation step prior to compilation based on new keywords, but this will frustrate debugging and lead to other surprises. Generators tried to do this, but it doesn&#x27;t seem to have taken off, from the repos I&#x27;ve read.<p>Just my 2c
评论 #20456408 未加载
mattxxx将近 6 年前
I think this is the right decision. Error-handling the go-way focuses on <i>whether</i> a single operation failed, rather than <i>how</i> a set of operations failed.<p>In Python or Java, you see a lot of try-catches around blocks of code, which can obfuscate where the <i>source</i> of the error is, despite having particular handling for the <i>type</i> of error.<p>For systems code, I mostly care about whether something failed... like: - Was the socket opened? - Was the file created? - etc.
quotemstr将近 6 年前
With try, Go might have been a language I&#x27;d have enjoyed using. It&#x27;s a shame. Right now, I see Go as being anti-abstraction and anti-cleverness, and I&#x27;d rather not work on codebases in which the language of choice is designed to deter creativity and encourage monotony. Heavy use of Go is a big negative when I evaluate potential projects to work on.
评论 #20455213 未加载
评论 #20455214 未加载
评论 #20455253 未加载
评论 #20457007 未加载
评论 #20455258 未加载
drivebyops将近 6 年前
Great that they listened to the community
评论 #20455829 未加载
评论 #20455137 未加载
评论 #20455149 未加载
willbw将近 6 年前
Try not. Do. Or do not. There is no try.
评论 #20455478 未加载
segmondy将近 6 年前
Lack of try and go&#x27;s error handling is part of my attraction to go. Explicit handling of error is much better than implicit and having to guess how things might get handled.
评论 #20474443 未加载
badrabbit将近 6 年前
Has the idea of making the returned error implicit and handling(or discarding) of the return value mandatory been explored? Thinking on the lines of errno in C.
kerng将近 6 年前
Well, that seems like the most obvious feature add to Go.
mvndaai将近 6 年前
I think the proposal&#x27;s intent was great but had some serious issues.<p>I created my own proposal that I think addresses the issues. I would love some constructive feedback. <a href="https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;go&#x2F;issues&#x2F;33161" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;go&#x2F;issues&#x2F;33161</a>
staunch将近 6 年前
Thank you Go developers! Please keep the language minimal, opinionated, and never subject to the bikeshedding mobs!<p>It wouldn&#x27;t have been the end of the world but I&#x27;m glad to see Go still has alive the spirit that made it so popular in the first place.
dr01d将近 6 年前
This is why we have nice things!
politician将近 6 年前
I&#x27;m extremely happy about this, and am hopeful this approach to community feedback continues. I previously said that this was a fait accompli like Go modules, but now I will happily withdraw that criticism.<p>&#x2F;cheers
atombender将近 6 年前
I appreciate this change of heart, as I wouldn&#x27;t want a half-baked solution to make it into Go, but I hope they don&#x27;t just stop there.<p>What the try() proposal gets wrong is that it tries to automatically bounce the error back the stack, being equivalent to &quot;if err != nil { return }&quot;, which is ofte reasonable, but at the same time lacks the flexibility that current Go code has in terms of augmenting the error, or indeed handling it: You&#x27;d end up with try() calls for <i>some</i> things, but not all, so it&#x27;s just ironing out one wrinkle and not every wrinkle. The second argument to try() is too heavy-handed. What we need is easy, readable syntax for all cases.<p>In current Go code, people like the &quot;v, err := someFunc()&quot; syntax because it allows the happy path to stay in the current scope, with the secondary syntax &quot;if v, err :=&quot; introducing a new scope to avoid polluting the parent scope. If you&#x27;re in the current scope, your code stays flat and clean (although Go&#x27;s love of shadowing cause subtle).<p>In my opinion, we need a syntax that is similar to a &quot;catch&quot; block in other languages, but easier. Perhaps something like this:<p><pre><code> v := getName() check err: { return errors.Wrap(err, &quot;could not get name&quot;) } </code></pre> This allows you to handle the error and augment it, while not introducing anything magical. It&#x27;s exactly equivalent to an &quot;if v, err :=&quot;, but without introducing a new scope <i>and</i> not polluting the current scope with an error variable. This syntax would happily support fallthrough:<p><pre><code> v := getName() check err: { log.Printf(&quot;could not get name, ignoring: %s&quot;, err) } &#x2F;&#x2F; v is now the zero value </code></pre> And of course you could still support a syntax for introducing a new scope:<p><pre><code> if v := getName() { &#x2F;&#x2F; v is now valid } check err: { &#x2F;&#x2F; You can return or anything else } </code></pre> You could easily extend it to error types with some kind of matching syntax:<p><pre><code> v := getName() check err == io.EOF { &#x2F;&#x2F; On EOF } check err: { &#x2F;&#x2F; All other errors } </code></pre> The above syntaxes don&#x27;t support chaining. I&#x27;m on the fence. I like Rust&#x27;s &quot;?&quot; postfix syntax, and I think it could work:<p><pre><code> &#x2F;&#x2F; This could be &quot;monadic&quot;; the first error short-circuits ceo := getPerson()?.getCompany()?.getCEO() check err: { return errors.Wrap(err, &quot;couldn&#x27;t get CEO&quot;) } </code></pre> But why not just let &quot;.&quot; be smart about errors and fall through like this?<p><pre><code> ceo := getPerson().getCompany().getCEO() check err: { return errors.Wrap(err, &quot;couldn&#x27;t get CEO&quot;) } </code></pre> After all, &quot;.&quot; can know if the function returns multiple values, and &quot;.&quot; on a tuple (or whatever Go calls it) isn&#x27;t valid, so why not &quot;promote&quot; the &quot;.&quot; to a high-level operator here?<p>The awkwardness of the try proposal goes deeper than just error handling, too, I think. One reason Go can&#x27;t solve its error handling problem <i>elegantly</i> is because of its reliance of multiple, exclusive return types. Almost all functions with this signature:<p><pre><code> func getName() (string, error) </code></pre> ...obey the unwritten rule that the function returns <i>either</i> a valid value, or an error. If you get an error, the value is supposed to be unusable, and the way to check for it is to look at whether there was an error.†<p>In many type systems, a situation where a return value can be <i>either</i> A or B is variously called a union, or discriminated union, or enum, or sum type, which is the term I prefer. It&#x27;s always bugged me that Go&#x27;s designers didn&#x27;t go one step further and made sum types a first-class citizen, because I think it would fit Go rather nicely. TypeScript solves it this way:<p><pre><code> function getName(): string | number </code></pre> And you can also define types this way:<p><pre><code> type number = int | float64 </code></pre> This, incidentally, introduces the idea of optional values:<p><pre><code> function takesOptional(x: string | null) </code></pre> Back to error handling, it would be more natural for a function to declare itself this way:<p><pre><code> func getName() string | error </code></pre> After all, it returns a value <i>or</i> an error. It can never be the superposition of both.<p>In this regime, anything that gets a value needs to explicitly check for what it is. &quot;switch&quot; on type would work, just like today, but that gets verbose for mere errors. So we just say that the &quot;check&quot; syntax as outlined above would work for any union that involves an error. In other words:<p><pre><code> func getThing() Person | Company | error { ... } thing := getThing() check err: { return errors.Wrap(err, &quot;can&#x27;t get thing&quot;) } </code></pre> We can do this because we can say that &quot;error&quot; is special and known to the compiler, just like make() etc. are special.<p>Of course, sum types go beyond errors, and open other avenues that are very poorly served by Go right now.<p>---<p>† This, unfortunately, isn&#x27;t universally true. For example, io.Reader&#x27;s Write() method&#x27;s contract says that if it returns io.EOF, it may still have read a final amount of data into its buffer. Many get this wrong and ignore the data read. Which points to the problem of conventions that only <i>seem</i> like unwritten rules, but also highlights how the lack of strong type-system support creates the issue in the first place.
hnaccy将近 6 年前
&gt;The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
评论 #20455365 未加载
评论 #20455403 未加载
RandomInteger4将近 6 年前
&quot;Do or do not. There is no try.&quot; ~ Golang master Yoda
kadendogthing将近 6 年前
This reads like script kiddies who became professional programmers and just want things done how they&#x27;ve always been done.<p>Error handling in go is not concise, and calling it explicit is in insult to anyone with a modicum of abstract reasoning skills. Error handling in go is not explicit, it&#x27;s verbose. Error handling in go is not concise, it&#x27;s broad. Error handling in Go is not consistent, it&#x27;s an exercise left up to diligent programmers.<p>As golang&#x27;s code base grows, you&#x27;re going to see this mistake play out over and over and over again.<p>Having a Result&lt;T&gt; construct would have been great for go.
patientplatypus将近 6 年前
I mean...<p>If you don&#x27;t like writing `if err!=nil {...}` throughout your code base surely you can just create some middleware function in its own package that has switch statements based on error cases. Checking for errors frequently in the running of the code is more or less a Good Thing.
评论 #20455468 未加载
评论 #20455455 未加载
hnruss将近 6 年前
Do or do not, there is no &#x27;try&#x27;.
poweroftrue将近 6 年前
Thank God!
评论 #20455070 未加载
eweise将近 6 年前
No wonder people are leaving in droves for Go++.
Zenst将近 6 年前
I hope somebody submits a &quot;Do&quot; and a &quot;Do Not&quot; amendment. Think of Yoda.