Interfaces are an interesting concept to learn in GOLANG. There are a tonne of informative articles and here is my contribution to it.
In classical Object Oriented everything is treated in parlance of Object or Class like in Java or C++. In Go there is no class or inheritance.
Learn by doing#
I started of by defining an interface
type MyInterface interface {
Set(int)
Get() int
}Which exposes two methods Get and Set and any user defined object that implements it (as shown below) can be assigned.
What it represents?#
Let’s try and print the value and type for a var of type MyInterface
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the valuevar myIntf MyInterface
fmt.Printf(" Before assigning the object %T %#v\n", myIntf, myIntf)The output might surprise you - for those coming from the Java background.
Before assigning the object <nil> <nil>The var myIntf is essentially a pointer with a value of nil.
- There is no explicit
implementslike verb ingo - The interface can be implemented by any number of
types - Multiple interfaces can be implemented by the same
type
Full Program#
package main
import "fmt"
// MyInterface defines simple set and get
type MyInterface interface {
Set(int)
Get() int
}
// Simple Struct that has only a single Value
type Simple struct {
u int
}
// Set the value for Simple struct
func (p *Simple) Set(u int) {
p.u = u
}
//Get returns the value in struct
func (p Simple) Get() int {
return p.u
}
func main() {
simple := &Simple{u: 20}
simple2 := Simple{u: 21}
fmt.Printf(" Value: %T %#v\n", simple, simple)
fmt.Printf(" Value: %d\n", simple.Get())
var myIntf MyInterface
fmt.Printf(" Before assigning the object %T %#v\n", myIntf, myIntf)
myIntf = simple
myIntf.Set(22)
fmt.Printf(" Value: %T %#v\n", myIntf, myIntf)
fmt.Printf(" Value: %d\n", myIntf.Get())
myIntf = &simple2
myIntf.Set(24)
fmt.Printf(" Value: %T %#v\n", myIntf, myIntf)
fmt.Printf(" Value: %d\n", myIntf.Get())
}Output#
API server listening at: 127.0.0.1:19141
Value: *main.Simple &main.Simple{u:20}
Value: 20
Before assigning the object <nil> <nil>
Value: *main.Simple &main.Simple{u:22}
Value: 22
Value: *main.Simple &main.Simple{u:24}
Value: 24Multiple Interfaces#
How about adding another interface
//Print can do anything
type Print interface {
Print()
}//Print Wildcard print
func (p *Simple) Print() {
fmt.Printf("Type: %T\nValue: %+v\n", p, p)
}I modified the main code like below to invoke print.
func main() {
simple := &Simple{u: 20}
simple2 := Simple{u: 21}
fmt.Printf(" Value: %T %#v\n", simple, simple)
fmt.Printf(" Value: %d\n", simple.Get())
simple.Print()
var myIntf MyInterface
fmt.Printf(" Before assigning the object %T %#v\n", myIntf, myIntf)
myIntf = simple
myIntf.Set(22)
fmt.Printf(" Value: %T %#v\n", myIntf, myIntf)
fmt.Printf(" Value: %d\n", myIntf.Get())
var print Print
print = simple
print.Print()
myIntf = &simple2
myIntf.Set(24)
fmt.Printf(" Value: %T %#v\n", myIntf, myIntf)
fmt.Printf(" Value: %d\n", myIntf.Get())
print = &simple2
print.Print()
}Output#
API server listening at: 127.0.0.1:36898
Value: *main.Simple &main.Simple{u:20}
Value: 20
Type: *main.Simple
Value: &{u:20}
Before assigning the object <nil> <nil>
Value: *main.Simple &main.Simple{u:22}
Value: 22
Type: *main.Simple
Value: &{u:22}
Value: *main.Simple &main.Simple{u:24}
Value: 24
Type: *main.Simple
Value: &{u:24}Or, adding another type
//Age struct a siple numberic holder
type Age struct {
a myInt
}
//Print Wildcard print
func (p *Age) Print() {
fmt.Printf("Type: %T\nValue: %+v\n", p, p)
}age := &Age{a: 40}
age.Print()
print = age
print.Print()Age only implements Print, so in case if we try to use it with the type MyInterface

Value: &{u:24}
Type: *main.Age
Value: &{a:40}
Type: *main.Age
Value: &{a:40}
