-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Go 2: Add a new operator to pass error between calls. #64493
Comments
This is just the |
This seems like a duplicate of an earlier proposal that was explored in detail, and is thus a likely decline. Leaving open for four weeks of final comments. |
I suggest this. But if the developers of the Go language think about it, I think it could be quite possible to implement it. I have an idea how to additionally simplify error handling in Go, but without add new keywords and obey backward compatibility in Go also for mixed use of old and new style, only need create a special type like swap err type to special type for compiler. In addition to For example, defer in Go already performs a role similar to scope(exit) in the D programming language. Go lacks scope(failure) and scope(success) or their analogues, but if you do it in Go it will return the error value to the upper scope. It would be much more convenient and beautiful than trying to do an analogue of try. This is we have now: package main
import (
"log"
"os"
)
func work(n string) error {
f, err := os.Open(n)
if err != nil {
log.Fatal(err)
return err
}
defer f.Close()
_, err = f.Stat()
if err != nil {
log.Fatal(err)
return err
}
return nil
}
func main() {
n := "/tmp/myfile.txt"
err := work(n)
if err != nil {
log.Fatal(err)
}
} You have been trying for years now to come up with a way to simplify error handling down to 1 line, this is the most realistic solution. Automatic error forwarding to the upper scope. And so that explicit error handling remains in the Go language. It would be nice if Go could do something like this: package main
import (
"log"
"os"
)
func work(n string) error {
f, err.(failure) := os.Open(n) // If err.(failure) != nil, then automatically returns err
defer f.Close() // Not executed after err.(failure) != nil
_, err.(failure) = f.Stat() // If err.(failure) != nil, then automatically returns err
return nil // Not executed after err.(failure) != nil
}
func swork(n string) (string, error) {
f, err.(failure) := os.Open(n) // If err.(failure) != nil then automatically returns err and string value as "" value. For another types also default values, empty structs etc...
defer f.Close() // Not executed after err.(failure) != nil
_, err.(failure) = f.Stat() // If err.(failure) != nil then automatically returns err and string value as "" value. For another types also default values, empty structs etc...
return "", nil // Not executed after err.(failure) != nil
}
func main() {
n := "/tmp/myfile.txt"
//err.(failure) := work(n) // failure in this case automatically generates panic, because this is main scope
err := work(n) // classic error handling
if err != nil {
log.Fatal(err)
}
//s, err.(failure) := swork(n) // failure in this case automatically generates panic, because this is main scope
s, err := swork(n) // classic error handling
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
} |
No change in consensus, so declined. |
Go Programming Experience
Experienced
Other Languages Experience
Go, C, Scala, Kotlin
Related Idea
Has this idea, or one like it, been proposed before?
No.
Does this affect error handling?
No.
It just simplifies the syntax of passing error and avoid most
if err != nil { return 0, nil, error }
statements which don't really handle the errors.Is this about generics?
No.
Proposal
It is really a pain when write codes about analysis intensive tasks (such as compilers) in current Go version. The codes around passing errors take much!
Add a new operator or use existing token to simplify
if err != nil { return ...(zero values)..., err }
to reduce the codes around error checking, passing and handling.Language Spec Changes
A new operator.
This operator allows hiding received error (from callee) in user code and passing the error to the caller if the error is not nil.
Informal Change
Old style:
New style:
Is this change backward compatible?
Yes.
Orthogonality: How does this change interact or overlap with existing features?
Passing the occurred error through the last return value (and is type of error) with an operator.
Would this change make Go easier or harder to learn, and why?
Easier.
Reducing the monotonous "if err != nil``" blocks that don't really handle but pass errors makes the main logic clear.
Cost Description
Changes to Go ToolChain
Go compiler frontend, Gopls.
Performance Costs
Compile time cost changes slightly. Almost no runtime cost.
Prototype
Write a new implementation of "go/ast.Expr" for this operator, which wraps "go/ast.CallExpr".
Possible implementations to translate the node:
... := Callee()!!!
=>..., err_or_else := Callee(); if err_or_else != nil { return ..., err }
The text was updated successfully, but these errors were encountered: