Why Golang Interface is not Equal to Nil

Damindu Lakmal
3 min readJan 28, 2024

--

Golang Interface

Golang is an open-source programming language developed by Google. It was created by Robert Griesemer, Rob Pike, and Ken Thompson and was first released in 2009. Go is designed to be efficient, readable, and productive, particularly in large-scale software development environments.

In Golang, interface is define as type which has set of method signatures. It shows the contract of types(struct) behaviour in abstract manner without specifying the interface.

Why we Need Interface

Interface are useful because of following properties,

  • Definition: An interface defines a list of method signatures
  • Polymorphism: Interfaces enable polymorphism, allowing different types to be treated interchangeably if they implement the same interface. This promotes code reusability and flexibility
  • Abstraction: Interfaces provide a way to define abstract behaviors without specifying the implementation details
  • Composition: A type can implement multiple interfaces, enabling flexible composition of behaviours
  • Duck typing: In languages like Go, interfaces are implemented implicitly, meaning a type automatically satisfies an interface if it has the required methods, regardless of whether it declares that it implements the interface.
package main

import "fmt"

type SampleInterface interface {
M()
}

type SampleStruct struct {
S string
}

// This method means type SampleStruct implements the interface SampleInterface,
// but we don't need to explicitly declare that it does so.
func (s SampleStruct) M() {
fmt.Println(s.S)
}

func main() {
//define as interface type
var i SampleInterface = SampleStruct{"hello"}
i.M()
}

How Interface Behave

In Golang, interface are implemented as two elements,

  • type : Corresponding type of the value
  • value : concrete value such as types(basic or custom), struct and pointers

For example, if we assign integer value 5 to an interface then the result interface type equal to int and value is 5. Interface value is dynamic according to the corresponding type which can be change during the execution of the program.

Untyped Nil

As we explain above, interface will be nil only if type and value are both unset. That means value is not set and type is equal to nil. Futhermore, a nil interface will always hold nil type. If we store a nil pointer of type without assigned value, interface type is pointer type but it doesn’t have any value. As a example, if we declare integer pointer without actual value then it will remain as nil value. In that case interface is not nil and that will be panic if you consider it has value.

Example of panic code

package main

func main() {
// ch field is not declare so it should be nil
e := check{}
p := e.check()
if p == nil {
print(`null`) // skip
}else{
print(`not null`) // -> print `not null`
// p.check() : panic code
}
}

type Check interface {
check() Check
}

type check struct {
ch *check
}

func (c *check) check() Check {
// check weather ch is nil or not before return the value
return c.ch
}

above code will be panic when you call p.check(). Nil check is not catch the nil value.

Summery

Interfaces in Go provide a flexible way to achieve polymorphism and abstraction, allowing different types to be treated uniformly if they implement the same interface. Understanding how interfaces behave, including their dynamic nature and nil handling, is crucial for writing effective and robust Go code.

--

--