I'm a Go newcomer, but I have read that Go regulars do not miss parametric polymorphism. Every time I try to learn a new language I use the L99 list of problems to get some practice.
Even if I try to write something as trivial as the first problem (which in Go would be a single statement, taking the last element of a slice), how would I write this as a function that takes a slice of any type and (using that single statement I referenced above) returns the last element of that slice?
I figured even though the language does not have parametric polymorphism there must be some idiomatic 'Go' way of doing this in order for Go regulars to claim they dont miss parametric polymorphism. Otherwise, if the example were more complex than just the last element of a list for instance, you would need a function to perform your task for every type.
What am I missing?
You cite the "99 lisp problems", yet Lisp does not have parametric polymorphism or static types at all.
Many statically-typed languages, like Objective-C, and Java before generics, have no parametric polymorphism. The solution is to just use a type that can accept all values, which in Go is interface{}
, and cast when you need to get some specific type out of it.
For your specific question, how to take "any type of slice"; unfortunately, there is no interface that includes specifically slices, since slices do not have any methods; so you'll be stuck with using interface{}
. Since you have an unknown slice type, you need to use reflection (the reflect
package) to perform all the slice operations, including getting the length and capacity, appending, and accessing the element at a particular index.
Another alternative is that instead of using "slice of any type", just use "slice of interface{}" i.e. []interface{}
, in all your code, then you can use the normal slice operators on it, and you can put any elements in, but cast when you get them out.