Skip to content

Instantly share code, notes, and snippets.

@nicerobot
Last active November 26, 2020 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicerobot/413e4472700003627957d590700752db to your computer and use it in GitHub Desktop.
Save nicerobot/413e4472700003627957d590700752db to your computer and use it in GitHub Desktop.
Simple demonstration of how nil pointers are not nil interfaces
package main
import (
"fmt"
"os"
)
func main() {
// p is not an interface. it is a pointer to a struct https://golang.org/pkg/os/#PathError
var p *os.PathError
fmt.Printf("%5v %p %[3]T %[3]v\n", p == nil, &p, p)
// err is an interface
var err error
fmt.Printf("%5v %p %[3]T %[3]v\n", err == nil, &err, err)
// Assinging p to error is effectively like a type-cast and works since
// a `*os.PathEror` is assignable to `error` because
// T is an interface type and x implements T.
// `error` is an interface type and `*os.PathEror` implements `error`. https://golang.org/pkg/os/#PathError.Error
// https://golang.org/ref/spec#Assignability:~:text=T%20is%20an%20interface%20type%20and%20x%20implements%20T.
err = p
fmt.Printf("%5v %p %[3]T %[3]v\n", err == nil, &err, err)
// This may make it more clear.
// Ignoring that error is a specific type of interface,
// this otherwise works exactly the same.
// Since everything is assignable to the empty interface.
var empty interface{}
fmt.Printf("%5v %p %[3]T %[3]v\n", empty == nil, &empty, empty)
empty = p
fmt.Printf("%5v %p %[3]T %[3]v\n", empty == nil, &empty, empty)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment