Another approach at generalizing these types of operations is to allow
the collections to apply a function to each element within. So in this
example I create an Eachable interace that means a collection provides
an Each function that will take as a parameter a function to apply to
all of the elements in turn.
Again, I'd appreciate feedback.
==== eachable.go ====
package eachable
type Eachable interface {
Each(func (interface{}))
}
==== myslice.go ====
package myslice
type MySlice []interface{}
func (s *MySlice) Each(f func(interface{})) {
for i := 0 ; i < len(*s) ; i ++ {
f((*s)[i])
}
}
==== mylinkedlist.go ====
package mylinkedlist
type node struct {
value interface{}
next *node
}
type LinkedList struct {
head *node
}
func NewList() *LinkedList {
return &LinkedList{nil}
}
func (l *LinkedList) Insert(value interface{}) {
n := node{value, l.head}
l.head = &n
}
func (l *LinkedList) Each(f func (interface{})) {
for cursor := l.head ; cursor != nil ; cursor = cursor.next {
f(cursor.value)
}
}
==== eachable-test.go ====
package main
import (
"fmt"
"./eachable"
"./myslice"
"./mylinkedlist"
)
func list(collection eachable.Eachable) {
count := 0
collection.Each(
func (v interface{}) {
count++;
fmt.Println(v);
})
fmt.Printf("%d items seen\n", count);
}
func average(collection eachable.Eachable) {
var count int = 0
var total float32 = 0.0
collection.Each(
func (v interface{}) {
count++;
switch v.(type) {
default:
count--;
case int:
total = total + float32(v.(int))
case float32:
total = total + v.(float32)
case float64:
total = total + float32(v.(float64))
}})
fmt.Printf("%d items seen\n", count);
fmt.Printf("The mean is %f\n", total / float32(count));
}
func main() {
array := []interface{}{3, 1.0, "four", 1, 5, 9}
slice := myslice.MySlice(array[:])
list(&slice)
ll := mylinkedlist.NewList()
ll.Insert(9)
ll.Insert(5)
ll.Insert(1)
ll.Insert("four")
ll.Insert(1.0)
ll.Insert(3)
list(ll)
average(&slice)
average(ll)
}