Interface Slices — Golang

Empty interfaces match to any type — what about empty interface slices

Saif Abid
3 min readJul 20, 2014

--

If you’re new to golang or have been playing around with it for a while, I’m sure you’ve become accustomed to the beauty of the empty interface.

var empty interface{}  

One of the many uses of an empty interface is generic typed functions. For example :

func p (thing interface{}){  fmt.Println(thing) }func main (){  p("Hello World")   p(12)}

In the case above, because every “type” (string,int etc) meets the requirement of the empty interface, it can be used in the function as a parameter.

Now what about something like this?

func main() { var anything []interface{} var stringList []string stringList = append(stringList, “first word”)
stringList = append(stringList, “Second word”)
stringList = append(stringList, “Third word”)
anything = stringList}

This seems correct right? We define a slice of empty interface, then a slice of strings and because an empty interface can be “any type” as seen in the previous example, we assign the slice of strings to the interface. Saying it like this makes sense, however the output is this :

cannot use stringList (type []string) as type []interface {} in assignment

So what happened?

The slice of interfaces is not a type itself, it is merely a “collection” of individual interfaces. Or in other words, each item in the anything “collection” is an empty Interface{}.

Lets see the fix then maybe this will make more sense.

 var anything []interface{} var stringList []string stringList = append(stringList, “first word”)
stringList = append(stringList, “Second word”)
stringList = append(stringList, “Third word”)
for _, val := range stringList {anything = append( anything , val )}fmt.Println(anything)}output : [first word, Second word, Third word]

Take a look at the for loop, thats where the magic is happening. In plain english it reads , “ for the range of our stringList , take each value (val) and append it to our collection named anything”

Now let’s go over one final example to really stress the idea of

Each element in the collection is of the empty interface type


func main() {
var anything []interface{} var stringList []string stringList = append(stringList, “first word”)
stringList = append(stringList, “Second word”)
stringList = append(stringList, “Third word”)
for _, val := range stringList {
anything = append(anything, val)
} // this loop just appened the list of strings to our anything collection
// lets now define a interger list var intList []int intList = append(intList, 1)
intList = append(intList, 2)
intList = append(intList, 3)
intList = append(intList, 4)
for _, val := range intList {
anything = append(anything, val)
}
fmt.Println(anything)}output: [first word, Second word, Third word, 1, 2, 3, 4]

As you can see, in this example, we created another list, this time of ints and then appended that to the anything list which just had strings added to it.

Why does this work? Because of the underlying definition :

Each element in the collection is of the empty interface type

The first three element are strings , which meet the criteria of the empty interface

The last four elements are integers, which also meet the criteria of the empty interface.

Going back, we can see that doing the assign which we had tried at the start just doesn’t make much sense now, as it would mean we could never add the integer list to our slice of empty interfaces.

--

--

Saif Abid

Data Science & Server @ecobee, Data Sci Educator @Brsinststion. Fmr: CTO @SwiftPadIO, Data @Wattpad. Electrical and Computer Engineering Alumni @UofT.