Skip to content

Instantly share code, notes, and snippets.

@maxk42
Last active May 19, 2018 06:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxk42/8329867 to your computer and use it in GitHub Desktop.
Save maxk42/8329867 to your computer and use it in GitHub Desktop.
Simple demonstration of generics-like features in Go.

POLYMORPHISM AND GENERICS IN GO

Lately, Go has been getting a lot of flack for its lack of generics and parametric polymorphism. Whereas it doesn't have a specific language feature called "generics", generic type operations are very simple to implement. Here is a simple implementation of a generic collection type in Go demonstrating how it's done. Essentially, the type interface{} acts as a placeholder for any type. By making use of the empty interface, you can pass any type to a function much like you can in dynamically-typed languages.

Edit: Thanks to https://gist.github.com/mfenniak and https://gist.github.com/dominikh for pointing out that the add() function was equivalent to go's built-in append()

package main
import (
"fmt"
"reflect"
)
type CustomCollection struct {
myElements []interface{}
}
func (c *CustomCollection) init() {
c.myElements = nil
}
func (c *CustomCollection) add(element interface{}) {
c.myElements = append(c.myElements, element)
}
func main() {
stringCollection := []string{"one", "two", "three"}
intCollection := []int{1, 2, 3}
fmt.Println("The value of stringCollection is: ", stringCollection)
fmt.Println("Now let's add it to a custom collection...")
myCollection := new(CustomCollection)
for _, v := range stringCollection {
myCollection.add(v)
}
fmt.Println("The value of myCollection.myElements is: ", myCollection.myElements)
fmt.Println("The type of myCollection.myElements is: ", reflect.TypeOf(myCollection.myElements))
fmt.Println("Now let's do it with ints...")
fmt.Print("The value of intCollection is: ", intCollection, "\n\n")
fmt.Println("And now we're creating a custom collection with the same values...")
myCollection = new(CustomCollection)
for _, v := range intCollection {
myCollection.add(v)
}
fmt.Println("The value of myCollection.myElements is: ", myCollection.myElements)
fmt.Println("The type of myCollection.myElements is: ", reflect.TypeOf(myCollection.myElements))
}
@mfenniak
Copy link

mfenniak commented Jan 9, 2014

Although this has nothing to do with your polymorphism, you should know your "add" method can be quite a bit simpler if you use the builtin append() method. "c.myElements = append(c.myElements, element)" would replace the entire function implementation, except possibly a nil check on c.myElements.

@dominikh
Copy link

dominikh commented Jan 9, 2014

@mfenniak append works just fine on nil slices, due to the simple fact that capacity for nil slices is defined as 0.

(On a side note, it would also make add a lot more efficient)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment