example.com$ cat >./main.go <<EOF
package main
import (
"errors"
"fmt"
"net"
)
func main() {
const addr = "••••••••"
conn, err := net.Dial("tcp", addr)
if err != nil {
if errors.As(err, (*net.InvalidAddrError)(nil)) {
fmt.Println("invalid address: %s")
}
}
defer conn.Close()
}
EOF
example.com$ cat >./go.mod <<EOF
module example.com
go 1.12
EOF
example.com$ go version
go version devel +33fdc10a30 Wed Apr 17 13:37:58 2019 -0400 linux/amd64
example.com$ go run main.go
errors.As being useful for type-checks even if I don't want to allocate space to store the result.
For this specific example:
invalid address: ••••••••
panic: errors: target must be a non-nil pointer
goroutine 1 [running]:
errors.As(0x54de60, 0xc000098000, 0x507020, 0x0, 0x0)
/usr/local/google/home/bcmills/go/src/errors/wrap.go:86 +0x5eb
main.main()
/tmp/tmp.8hp5hhWBDQ/example.com/main.go:13 +0xd5
exit status 2
This is the documented behavior of errors.As, but it seems strictly less useful than allowing a nil pointer of a concrete type.
(See previously #30970, which relaxed a somewhat related constraint on err.)
CC @neild @jba @mpvl
I don't see a problem with this.
An error matches a type ... if it has a method As(interface{}) bool such that As(target) returns true.
So what should the As method of the error do if target is nil? Should all As method implementation check for nil pointers? Wouldn't this place a burden on all interface implementors?
--
An aside: the As function is currently documented:
An error matches a type if it is assignable to the target type,
Should that be "assignable through"? It only matches if the given error (or an unwrapped error) can be assigned to the "element" value of target. This seems like it needs some clarification.
Change https://golang.org/cl/179978 mentions this issue: errors: As target can be a typed nil pointer
Should all
Asmethod implementation check fornilpointers? Wouldn't this place a burden on all interface implementors?
That's true.
Should that be "assignable through"?
In the same CL linked above, I reworded that part of the doc. PTAL.
I think this API change is a mistake, for the reasons adg gives above.
It's a minor performance optimization that will cause problems in every As method implementation. It doens't balance out.
Abandoned the CL.
Most helpful comment
So what should the
Asmethod of the error do iftargetisnil? Should allAsmethod implementation check fornilpointers? Wouldn't this place a burden on all interface implementors?--
An aside: the
Asfunction is currently documented:Should that be "assignable through"? It only matches if the given error (or an unwrapped error) can be assigned to the "element" value of target. This seems like it needs some clarification.