naixyeur
(NaixYeur)
November 17, 2020, 6:28am
1
Below codes are about a function that returning nil custom error in two variations. Expectantly, these codes should always exit successfully, but it didn’t happen on Code 2.
Code 1
Code 2
If we change operation() return signature to error interface instead, Code 2 able to exit again.
func operation() ([]byte, error) {
return nil, nil
}
Can someone please explain the mechanism behind it? And what’s the difference between these two exactly? Thanks.
1 Like
lutzhorn
(Lutz Horn)
November 17, 2020, 7:41am
2
ermanimer
(erman imer)
November 17, 2020, 8:07am
3
In Code 2:
package main
import "fmt"
type customError struct{}
func (c *customError) Error() string {
return "custom error!"
}
func operation() ([]byte, *customError) {
return nil, nil
}
func main() {
var err error
fmt.Println(err) //here, err is a nil pointer to error interface
_, err = operation()
fmt.Println(err) //here, err is pointer to nil customError interface, err is not nil itself
if err != nil {
println("ERROR!!!! ARRG!")
return
}
println("peace out")
}
You can see the output here: https://play.golang.org/p/uvtktWe2MlS
You can fix Code 2 as following:
package main
type customError struct{}
func (c *customError) Error() string {
return "custom error!"
}
func operation() ([]byte, *customError) {
return nil, nil
}
func main() {
var err *customError
_, err = operation()
if err != nil {
println("ERROR!!!! ARRG!")
return
}
println("peace out")
}
You can see the fixed output here: https://play.golang.org/p/z4tVkriX30O
For better understanding please check following code:
package main
type customError struct{}
func (c *customError) Error() string {
return "custom error!"
}
func operation() ([]byte, *customError) {
return nil, nil
//return nil, &customError //how to return a custom error
}
func main() {
var err error
_, err = operation()
if err != (*customError)(nil) { //here, we are checking if err is not equal to a pointer to nil custom error
println("ERROR!!!! ARRG!")
return
}
println("peace out")
}
You can see the output here: https://play.golang.org/p/RhPkEOjl--p
2 Likes
petrus
(petrus)
November 17, 2020, 8:30am
4
Go: Frequently Asked Questions (FAQ)
Why is my nil error value not equal to nil?
For the original design for Go interfaces:
Go Data Structures: Interfaces
Posted on Tuesday, December 1, 2009.
For err == nil it has to have a type of nil and a value of nil, but err is set to a concrete type of *customError and a concrete value of nil and err != nil.
Instead, write:
package main
import "fmt"
type customError struct{}
func (c *customError) Error() string {
if c == nil {
return "custom nil!"
}
return "custom error!"
}
func operation() ([]byte, *customError) {
return nil, nil
}
func main() {
var err error
fmt.Printf("%[1]T %[1]v\n", err)
_, err = operation()
fmt.Printf("%[1]T %[1]v\n", err)
if v, ok := err.(*customError); ok && v != nil {
println("ERROR!!!! ARRG!")
return
}
println("peace out")
}
<nil> <nil>
*main.customError custom nil!
peace out
4 Likes
naixyeur
(NaixYeur)
November 17, 2020, 11:12am
5
Thanks, Petrus! the FAQ hits the spot. The article about go interface is worth giving a read.
Appreciate that you spend effort to answer my newb question.
1 Like
system
(system)
Closed
February 15, 2021, 11:12am
6
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.