Testing our empty interface-based Map function
We'll test our new empty interface-based Map function by defining a transformation function. This function will multiply every item in the collection by 10:
func main() {
transformation10 := func(curVal, _, _ Object) Object {
return curVal.(int) * 10 }
result := Map(Collection{1, 2, 3, 4}, transformation10)
fmt.Printf("result: %vn", result)
We pass a collection of the numbers 1, 2, 3, and 4 as well as the transformation function.
The output will be as follows:
result: [10 20 30 40]
Now, let's pass our Map function a collection of strings:
transformationUpper := func(curVal, _, _ Object) Object { return strings.ToUpper(curVal.(string)) }
result = Map(Collection{"alice", "bob", "cindy"}, transformationUpper)
fmt.Printf("result: %vn", result)
}
This time we pass a collection of strings and transform each by calling ToUpper.
Here's the output:
result: [ALICE BOB CINDY]
Notice how in each case, we had to cast each curVal? With transformation10, we can cast each item in the collection to an int variable; with transformationUpper, we can cast each item to a string variable. We could choose to use reflection to avoid explicit casting, but that is even worse for performance than casting.
As with our earlier example, we could pass the collection to a chain of transformation functions to arrive at the result, which could be another collection or a single terminal value.
Instead of reinventing the wheel each time, we need another high-order function; let's use any one of the number of Go packages available that easily enable the functional style of programming in Go.