Golang泛型之any

4,587 阅读1分钟

概念

any是golang新引入的预定义标识符,是空接口的别名,可以用于代替interface{}

应用场景

在泛型场景下,可将any用于类型限定(type constraint),以表示任意类型。

在函数式编程时,经常会用到filter/map/reduce函数,这里就对其进行简单介绍。

定义泛型Filter

package slices

// Filter filters values from a slice using a predicate
// return a new slice contains elements of this slice which satisfy a predicate
func Filter[T any](s []T, predicate func(T) bool) []T {
	r := []T{}
	for _, e := range s {
		if predicate(e) {
			r = append(r, e)
		}
	}
	return r
}

相应样例及运行结果如下:

package main

import (
	"fmt"

	"github.com/skholee/generic-wheel/slices"
)

func main() {
	s := []string{"1", "11", "111", "1111"}
	p := func(s string) bool { return len(s) <= 2 }

	r := slices.Filter(s, p)
	fmt.Println("filter result: ", r)
}
$ go run .
filter result:  [1 11]

定义泛型Map

package slices

// Map used to apply a function to each element in slice
// return a new slice contains the transformed elements
func Map[S, D any](s []S, f func(S) D) []D {
	r := make([]D, 0, len(s))
	for _, e := range s {
		r = append(r, f(e))
	}
	return r
}

相应样例及运行结果如下:

package main

import (
	"fmt"

	"github.com/skholee/generic-wheel/slices"
)

func main() {
	s := []string{"1", "11", "111"}
	f := func(s string) int { return len(s) }

	r := slices.Map(s, f)
	fmt.Println("map result: ", r)
}
$ go run .
map result:  [1 2 3]

定义泛型Reduce

package slices

// Reduce reduces a slice down to a single value using a reduction function
func Reduce[S, D any](s []S, initializer D, f func(D, S) D) D {
	r := initializer
	for _, e := range s {
		r = f(r, e)
	}
	return r
}

相应样例及运行结果如下:

package main

import (
	"fmt"

	"github.com/skholee/generic-wheel/slices"
)

func main() {
	s := []string{"1", "11", "111"}
	f := func(l int, s string) int { return l + len(s) }

	r := slices.Reduce(s, 0, f)
	fmt.Println("reduce result: ", r)
}
$ go run .
reduce result:  6

后记

通过自定义泛型filter/map及reduce,我们基本对golang泛型中的any类型限定有了一个大体的了解,同时也为后续进行golang泛型编程提供了一些基本可用的轮子。

通过自定义泛型Dictionary及Set,我们基本对golang泛型中的comparable类型限定有了一个大体的了解,同时也为后续进行golang泛型编程提供了一些基本可用的轮子。

完整代码见:github.com/skholee/gen…

References

Golang泛型提案:go.googlesource.com/proposal/+/…