Continue - Empty Interfaces in Go
Sheary Tan
Posted on July 25, 2018
Empty interface
As the name stated, it does not contain any methods. This is useful when we want to store different types of data.
From the previous post, we only use numbers for our example. What if we want to include different types of data?
For example:
package main
import "fmt"
type animal struct {
age int
color string
sound string
}
type cat struct {
animal
bossy bool
}
type dog struct {
animal
friendly bool
}
func main() {
cassy := cat{animal{3, "white", "meow"}, true}
kitty := cat{animal{2, "black", "meow"}, true}
missy := cat{animal{1, "brown", "meow"}, true}
cats := []cat{cassy, kitty, missy}
rocky := dog{animal{4, "brown", "woof"}, true}
lucy := dog{animal{3, "white", "woof"}, true}
tucker := dog{animal{2, "black", "woof"}, true}
dogs := []dog{rocky, lucy, tucker}
for i, val := range cats {
fmt.Println(i, " - ", val)
}
for i, val := range dogs {
fmt.Println(i, " - ", val)
}
}
// 0 - {{3 white meow} true}
// 1 - {{2 black meow} true}
// 2 - {{1 brown meow} true}
// 0 - {{4 brown woof} true}
// 1 - {{3 white woof} true}
// 2 - {{2 black woof} true}
It is a simple code so I don't think I would need to explain here...Well alright.. So we have two types here with dog()
and cat()
, bunch of dogs and cats, and two for loops to loop through the dogs
and cats
and finally print out the dogs and cats.
See the problem here? Same as the previous post, why do we need to write two different functions (in this case it's the for loops) to do the same thing?
But what's different from the previous post is that we have different types here: int
, string
, and bool
in the type
.
Instead why don't we include our friend interface:
package main
import "fmt"
type animals interface{}
type animal struct {
age int
color string
sound string
}
type cat struct {
animal
bossy bool
}
type dog struct {
animal
friendly bool
}
func main() {
cassy := cat{animal{3, "white", "meow"}, true}
kitty := cat{animal{2, "black", "meow"}, true}
missy := cat{animal{1, "brown", "meow"}, true}
rocky := dog{animal{4, "brown", "woof"}, true}
lucy := dog{animal{3, "white", "woof"}, true}
tucker := dog{animal{2, "black", "woof"}, true}
friends := []animals{cassy, kitty, missy, rocky, lucy, tucker}
for i, val := range friends {
fmt.Println(i, " - ", val)
}
}
// 0 - {{3 white meow} true}
// 1 - {{2 black meow} true}
// 2 - {{1 brown meow} true}
// 3 - {{4 brown woof} true}
// 4 - {{3 white woof} true}
// 5 - {{2 black woof} true}
So here we have got an empty animal interface, recall the statement of 'This is useful when we want to store different types of data.', we definitely have a bunch of different types for the type cat
and dog
.
It is difficult to specify which type do we need exactly, so why don't we just chuck everything into something(empty interface) that accept everything?
Or you can do this too:
Empty Interface as param
package main
import (
"fmt"
)
type animal struct {
age int
color string
sound string
}
type cat struct {
animal
bossy bool
}
type dog struct {
animal
friendly bool
}
func result(a interface{}) { // Here!
fmt.Println(a)
}
func main() {
cassy := cat{animal{3, "white", "meow"}, true}
rocky := dog{animal{4, "brown", "woof"}, true}
result(cassy)
result(rocky)
}
// {{3 white meow} true}
// {{4 brown woof} true}
Here I only included a dog and a cat just to reduce the complexity.
Or this:
Empty Interface as slice
package main
import "fmt"
type animal struct {
age int
color string
sound string
}
type cat struct {
animal
bossy bool
}
type dog struct {
animal
friendly bool
}
func main() {
cassy := cat{animal{3, "white", "meow"}, true}
kitty := cat{animal{2, "black", "meow"}, true}
missy := cat{animal{1, "brown", "meow"}, true}
rocky := dog{animal{4, "brown", "woof"}, true}
lucy := dog{animal{3, "white", "woof"}, true}
tucker := dog{animal{2, "black", "woof"}, true}
// Here!
friends := []interface{}{cassy, missy, kitty, rocky, lucy, tucker}
fmt.Println(friends)
}
// [{{3 white meow} true} {{1 brown meow} true} {{2 black meow} true} {{4 brown woof} true} {{3 white woof} true} {{2 black woof} true}]
Which will return a slice (array).
The basic idea of interface: to prevent the repetition when calling methods. Empty interface? To prevent the repetition when calling methods with different types.
Thank you for reading my post, I am still a newbie Gopher but working hard to become a qualified Gopher :3
Posted on July 25, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.