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()

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()

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()

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()

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()

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()

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

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))
}