« Back to Index

Interface Value vs Interface Type

View original Gist on GitHub

Tags: #go

Golang Interface Value vs Interface Type.md

Rereference:

Under the hood, interface values can be thought of as a tuple of a value and a concrete type:

(value, type)

Calling a method on an interface value executes the method of the same name on its underlying type.

package main

import (
	"fmt"
	"math"
	"reflect"
)

type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M() {
	//fmt.Println(t.S)
}

type F float64

func (f F) M() {
	//fmt.Println(f)
}

func main() {
	var i I

	i = &T{"Hello"}
	describe(i) // &{S:Hello}, *main.T
	i.M()

	// &{S:Hello}, *main.T
	fmt.Printf("%+v, %+v\n\n", reflect.ValueOf(i), reflect.TypeOf(i))

	i = F(math.Pi)
	describe(i) // 3.141592653589793, main.F
	i.M()

	// 3.141592653589793, main.F
	fmt.Printf("%+v, %+v\n", reflect.ValueOf(i), reflect.TypeOf(i))
}

func describe(i I) {
	fmt.Printf("%+v, %T\n", i, i)
}

When we assign to i which is the interface I, we’ll find that i ultimately holds the expected value (e.g. either a struct T or a float F) but the ‘type’ associated with the i variable isn’t actually the I interface (which you might have expected) it’s actually the type of the value that was assigned.