Skip to content

Instantly share code, notes, and snippets.

Last active April 7, 2022 04:55
What would you like to do?
Some code that will nil an interface's value while leaving its type intact.
package main
import (
// NullInterfaceValue takes an interface ref, constructs an new struct from
// the pointer, allowing us to modify the parts of the pointer, and sets the
// interface's value to nil.
func NullInterfaceValue(x *interface{}) {
e := (*emptyInterface)(unsafe.Pointer(x))
e.word = nil
func main() {
var uid interface{} = uuid.New()
switch val := uid.(type) {
case nil:
fmt.Println("value is nil")
case fmt.Stringer:
// Interfaces below are from the reflect package -- (c) Go Authors 2009/BSD.
// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
typ *rtype
word unsafe.Pointer
type rtype struct {
size uintptr
ptrdata uintptr // number of bytes in the type that can contain pointers
hash uint32 // hash of type; avoids computation in hash tables
tflag tflag // extra type information flags
align uint8 // alignment of variable with this type
fieldAlign uint8 // alignment of struct field with this type
kind uint8 // enumeration for C
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
equal func(unsafe.Pointer, unsafe.Pointer) bool
gcdata *byte // garbage collection data
str nameOff // string form
ptrToThis typeOff // type for pointer to this type, may be zero
type tflag uint8
type nameOff int32 // offset to a name
type typeOff int32 // offset to an *rtype
Copy link

mmorton commented Apr 7, 2022

I didn't see a way to comment on your blog post, so I'm posting this here, but you don't need to use the above to run into this situation. If you run the program below, you'll see some of the ways you can encounter this:

package main

import (

type SomeStruct struct {
	name string

func (o *SomeStruct) String() string {

var _ fmt.Stringer = (*SomeStruct)(nil)

func main() {
	var c fmt.Stringer = (*SomeStruct)(nil)

	var d *SomeStruct
	var e fmt.Stringer = d

	var f *SomeStruct = nil

func describe(i interface{}) {
	fmt.Printf("(v:%v, t:%T)\n", i, i)

func check(s fmt.Stringer) {
	if s == nil {
		fmt.Printf("is == nil.\n")
	if reflect.ValueOf(s).IsNil() {
		fmt.Printf("is != nil, reflect value is nil.\n")
	switch s.(type) {
	case nil:
		fmt.Printf("type is nil.\n")
	case fmt.Stringer:
		fmt.Printf("string is %s\n", s.String())

If you comment out the IsNil() reflection check, it will panic as expected.

Also, this happens often enough with error (an interface) that it is mentioned in the FAQ:

Nil receivers are by design as well, see:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment