Thanks to the new 1.18 beta release of Go, we can use new Generic feature. First thing I tried to do is to implement Map / Filter / Reduce to any slice.
So with a Generic Slice Type defined as :
type Slice[T any] []T
I can implements my two first methods Map and Filter as follows:
func (s Slice[T]) Map(callback func(item T, indice int, arr Slice[T]) T) Slice[T] {
temp := make([]T, 0)
for i, v := range s {
temp = append(temp, callback(v, i, s))
}
return temp
}
func (s Slice[T]) Filter(callback func(item T, indice int, arr Slice[T]) bool) Slice[T] {
temp := make([]T, 0)
for i, v := range s {
if callback(v, i, s) {
temp = append(temp, v)
}
}
return temp
}
This works fine as follows:
s := Slice[int]{1, 2, 3}
mapped := s.Map(func(item int, indice int, arr Slice[int]) int {
return item*2 + len(arr) + indice
})
fmt.Println(mapped) // Print : [5 8 11]
filtered := s.Filter(func(item int, _ int, _ Slice[int] ) bool {
return item%2==0
})
fmt.Println(filtered) // Print : [2]
Now, I'd like to implements my "Reduce" function, in the same way the Javascript Reduce works... In the Javascript version, we pass a callback with the accumulator, the current element, the index of the current element in the array and the array itself. It should return the accumulator; and a second argument: the initial value.
So, the slice should be generic over T
, but the accumulator could be another generic value
I tried to code something like:
func (s Slice[T]) Reduce[V any](callback func(accumulator V, current T) V, initial V) V {
...
}
With this signature, based on a slice of T
, my method will take a callback and an initial value of another generic type V
. The callback accumulator is from this second generic V
(and will return V) based on each current element of type T
.
Unfortunately this code produces:
syntax error: method must have no type parameters
It seems we can't use any other type parameter except one declared on the receiver.
Is there any solution for this use case?