Description
Proposes an exclamation identifier ! similar to the blank identifier for assignment. A non zero value assigned to ! causes a run-time error. For example:
f, ! := os.Open(filename) // panics on error
Related to the try proposal this proposal aims to simplify error boilerplate. Unlike the try proposal it can be used for any type. The value v assigned to ! effectively calls:
if !reflect.ValueOf(v).IsZero() {
panic(v)
}
I think this behaviour is similar to how type assertions panic on invalid non handled cases.
Maps can get similar behaviour with value, ! := myMap[key]
which would panic on missing key.
As a larger example Go by Example: Reading Files could be written as:
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
func main() {
dat, ! := ioutil.ReadFile("/tmp/dat")
fmt.Print(string(dat))
f, ! := os.Open("/tmp/dat")
b1 := make([]byte, 5)
n1, ! := f.Read(b1)
fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))
o2, ! := f.Seek(6, 0)
b2 := make([]byte, 2)
n2, ! := f.Read(b2)
fmt.Printf("%d bytes @ %d: ", n2, o2)
fmt.Printf("%v\n", string(b2[:n2]))
o3, ! := f.Seek(6, 0)
b3 := make([]byte, 2)
n3, ! := io.ReadAtLeast(f, b3, 2)
fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
_, ! = f.Seek(0, 0)
r4 := bufio.NewReader(f)
b4, ! := r4.Peek(5)
fmt.Printf("5 bytes: %s\n", string(b4))
f.Close()
}
This removes the check function and calls to check. The panic stack trace would be simplified as the call to check is removed. I could see this being used for example code and simple scripts where panics are already used for error handling.