Empty Interfaces in Golang

Eug picture Eug · Jan 29, 2020 · Viewed 13.9k times · Source

Edit: This is not the right way to use interfaces in Go. The purpose of this question is for me to understand how empty interfaces work in Go.

If all types in Go implement interface{} (empty interface), why can't I access the name field in the Cat and Dog structs? How can I get access to the name field of each struct through the function sayHi()?

package main

import (
    "fmt"
)

func sayHi(i interface{}) {

    fmt.Println(i, "says hello")

    // Not understanding this error message
    fmt.Println(i.name) //  i.name undefined (type interface {} is interface with no methods)
} 

type Dog struct{
    name string
}
type Cat struct{
    name string
}

func main() {
    d := Dog{"Sparky"}
    c := Cat{"Garfield"}

    sayHi(d) // {Sparky} says hello
    sayHi(c) // {Garfield} says hello
}

Answer

Burak Serdar picture Burak Serdar · Jan 30, 2020

An interface{} is a method set, not a field set. A type implements an interface if it's methods include the methods of that interface. Since empty interface doesn't have any methods, all types implement it.

If you need to access a field, you have to get the original type:

name, ok:=i.(Dog).name

This will recover the name if i is a Dog.

Alternatively, implement a getName() function for both Dog and Cat, and then they will both implement the following interface:

type NamedType interface {
   getName() string
}

Then you can rewrite your function as:

func sayHi(i NamedType) {
   fmt.Println(i.getName()) 
}