golang 使用范型方法
August 18, 2022 默认分类
Golang 使用范型方法
本文以实现一个简单算法为例子.
情况一
var oldSlice = []int{22, 23, 80, 443}
var newSlice = []int{80, 443}
fmt.Println(Integer(oldSlice, newSlice))
// result---> [81, 444]
情况二
var oldSlice = []int{22, 23, 80, 443}
var newSlice = []int{25, 8000}
fmt.Println(Integer(oldSlice, newSlice))
// result---> [25, 8000]
情况三
var oldSlice = []int{22, 23, 80, 443}
var newSlice = []int{23, 24}
fmt.Println(Integer(oldSlice, newSlice))
// result---> [25, 24]
源码
type signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type integer interface {
signed | unsigned
}
type compare[T integer] struct {
source, target, result []*T
}
func Integer[T integer](source, target []T) []T {
c := compare[T]{}
c.init(source, target)
for k, v := range c.target {
if !c.contains(c.source, v) {
c.result[k] = v
c.source = append(c.source, v)
c.target[k] = nil
}
}
for k, v := range c.target {
if v == nil {
continue
}
c.result[k] = c.compare(v)
}
return c.unConvert()
}
func (c *compare[T]) init(source, target []T) {
c.source = c.removeDuplicates(c.convert(source))
c.target = c.removeDuplicates(c.convert(target))
c.result = make([]*T, len(target))
}
func (c *compare[T]) compare(e *T) *T {
if c.contains(c.source, e) {
*e += 1
return c.compare(e)
}
c.source = append(c.source, e)
return e
}
func (c *compare[T]) removeDuplicates(source []*T) (target []*T) {
for _, v := range source {
if !c.contains(target, v) {
target = append(target, v)
}
}
return
}
func (c *compare[T]) contains(source []*T, target *T) bool {
for _, v := range source {
if *v == *target {
return true
}
}
return false
}
func (c *compare[T]) convert(s []T) (e []*T) {
for _, v := range s {
e = append(e, func(v T) *T {
return &v
}(v))
}
return e
}
func (c *compare[T]) unConvert() (e []T) {
for _, v := range c.result {
e = append(e, func(v *T) T {
return *v
}(v))
}
return e
}