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
}

GO训练场

添加新评论