# Golang 泛型试用 (2020/06版本) https://blog.golang.org/generics-next-step https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md https://go2goplay.golang.org/ ## `Min()` ```go import ( "fmt" ) type Ordered interface { type int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64 } func Min(type T Ordered)(s []T) (T, error) { var r T if len(s) == 0 { return r, fmt.Errorf("empty array") } for _, v := range s { if r > v { r = v } } return r, nil } func main() { fmt.Println(Min([]int{9, -1, 1, 0, 2, 4, 9, -10, 11})) } ``` ## `Choice()` ```go import ( "fmt" "math/rand" ) func Choice(type T)(xs []T) (T, error) { var r T sz := len(xs) if sz == 0 { return r, fmt.Errorf("empty array") } i := rand.Intn(sz) return xs[i], nil } func main() { for i := 0; i < 5; i++ { fmt.Println(Choice([]int{9, -1, 1, 0, 2, 4, 9, -10, 11})) } } ``` ## `Flat()` ```go import ( "fmt" ) func Flat(type T)(xss [][]T) []T { var ret []T for _, xs := range xss { ret = append(ret, xs...) } return ret } func main() { fmt.Println(Flat([][]int{{9, -1, 1}, {0, 2, 4}, {9, -10, 11}})) } ``` ## `Filter()` ```go import ( "fmt" ) func Filter(type T)(pred func(v T) bool, xs []T) []T { var ret []T for _, v := range xs { if pred(v) { ret = append(ret, v) } } return ret } func main() { fmt.Println(Filter(func(v int) bool { return v%2 == 0 }, []int{9, -1, 1, 0, 2, 4, -10, 11})) } ``` ## `Reverse()` ```go import ( "fmt" ) func Reverse(type T)(xs []T) []T { n := len(xs) ret := make([]T, n) for i := 0; i < n; i++ { ret[i] = xs[n-i-1] } return ret } func main() { fmt.Println(Reverse([]int{1, 2, 3, 4, 5})) } ``` ## `Dedup()` ```go import ( "fmt" ) func Dedup(type T comparable)(xs []T) []T { sz := len(xs) if sz == 0 { return xs } visited := make(map[T]struct{}, sz) var ret []T for _, v := range xs { if _, ok := visited[v]; ok { continue } else { ret = append(ret, v) visited[v] = struct{}{} } } return ret } func main() { rs := Dedup([]int{1, 2, 3, 4, 1, 2, 3, 5, 7, 4}) fmt.Println(rs) } ``` ## `Set` ```go import ( "fmt" ) type Set(type T comparable) struct { m map[T]struct{} } func NewSet(type T comparable)() *Set(T) { return &Set(T){m: make(map[T]struct{})} } func (s *Set(T)) Add(v T) { s.m[v] = struct{}{} } func (s *Set(T)) Remove(v T) { delete(s.m, v) } func (s *Set(T)) Contains(v T) bool { if _, ok := s.m[v]; ok { return true } return false } func (s *Set(T)) Card() int { return len(s.m) } func main() { s := NewSet(int)() s.Add(1) s.Add(2) fmt.Println(s.Contains(5)) fmt.Println(s.Contains(2)) } ```