参考 : https://blog.axiaoxin.com/post/go-generics/

求切片长度

package main

import "fmt"

func Length[T any](s []T) int {
	return len(s)
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	fmt.Println(Length[int](s))
	s2 := []string{"a", "b", "c", "d", "e"}
	fmt.Println(Length[string](s2))
}

泛型结构体

package main

type Box[T any] struct {
	value T
}

func (b Box[T]) GetValue() T {
	return b.value
}

func main() {
	b := Box[int]{value: 10}
	c := Box[string]{value: "Hello"}
	println(b.GetValue())
	println(c.GetValue())
}

使用泛型实现集合Set

package main

import "fmt"

type void = struct{}
type Set[T comparable] struct {
	data map[T]void
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{
		data: make(map[T]void),
	}
}

func (s *Set[T]) Add(item T) {
	s.data[item] = void{}
}
func (s *Set[T]) Remove(item T) {
	delete(s.data, item)
}

func (s *Set[T]) Has(item T) bool {
	_, ok := s.data[item]
	return ok
}
func (s *Set[T]) Clear() {
	s.data = make(map[T]void)
}
func (s *Set[T]) Len() int {
	return len(s.data)
}

func (s *Set[T]) ContainsAll(other *Set[T]) bool {
	if other.Len() == 0 {
		return true
	}
	if s.Len() < other.Len() {
		return false
	}
	for key := range other.data {
		if !s.Has(key) {
			return false
		}
	}
	return true
}

// 并集
func (s *Set[T]) Union(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for key := range s.data {
		result.Add(key)
	}
	for key := range other.data {
		result.Add(key)
	}
	return result
}

// 交集
func (s *Set[T]) Intersection(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for key := range s.data {
		if other.Has(key) {
			result.Add(key)
		}
	}
	return result
}

// 差集
func (s *Set[T]) Difference(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for key := range s.data {
		if !other.Has(key) {
			result.Add(key)
		}
	}
	return result
}

func (s *Set[T]) Iterate(fn func(key T)) {
	for key := range s.data {
		fn(key)
	}
}

func main() {
	// 创建一个整数集合
	set := NewSet[int]()
	set.Add(1)
	set.Add(2)
	set.Add(3)

	fmt.Println("集合元素:", set.Len())    // 输出:3
	fmt.Println("是否包含 2:", set.Has(2)) // 输出:true

	// 测试 Remove
	set.Remove(2)
	fmt.Println("移除后是否包含 2:", set.Has(2)) // 输出:false

	// 测试并集、交集、差集
	set2 := NewSet[int]()
	set2.Add(3)
	set2.Add(4)
	set2.Add(5)

	union := set.Union(set2)
	fmt.Println("并集元素数量:", union.Len()) // 输出:4(元素 1,3,4,5)

	intersection := set.Intersection(set2)
	fmt.Println("交集元素数量:", intersection.Len()) // 输出:1(元素 3)

	difference := set.Difference(set2)
	fmt.Println("差集元素数量:", difference.Len()) // 输出:1(元素 1)

	// 遍历集合
	set.Iterate(func(elem int) {
		fmt.Printf("元素: %d\n", elem)
	})
}

泛型通道

package main

type Channel[T any] struct {
	ch chan T
}

func NewChannel[T any](size int) *Channel[T] {
	return &Channel[T]{
		ch: make(chan T, size),
	}
}

func (c *Channel[T]) Send(value T) {
	c.ch <- value
}
func (c *Channel[T]) Receive() T {
	return <-c.ch
}