Go - 合并2个函数,其唯一的区别是参数类型

时间:2015-08-17 20:42:38

标签: go

我有两个几乎完全正确的功能:

1号

func mergeSlicesOfRequestObjects(aSliceDestination *[]RequestObject, aSliceSource []RequestObject) {
for _, oSliceSourceItem := range aSliceSource {
    // Get current key
    iIndexSourceItemFound := -1
    for iIndexAttribute, oSliceDestinationItem := range *aSliceDestination {
        if oSliceSourceItem.Key == oSliceDestinationItem.Key {
            iIndexSourceItemFound = iIndexAttribute
            break
        }
    }

    // Update attribute
    if iIndexSourceItemFound == -1 {
        *aSliceDestination = append(*aSliceDestination, oSliceSourceItem)
    }
}
}

2号:

func mergeSlicesOfResponseObjects(aSliceDestination *[]ResponseObject, aSliceSource []ResponseObject) {
for _, oSliceSourceItem := range aSliceSource {
    // Get current key
    iIndexSourceItemFound := -1
    for iIndexAttribute, oSliceDestinationItem := range *aSliceDestination {
        if oSliceSourceItem.Key == oSliceDestinationItem.Key {
            iIndexSourceItemFound = iIndexAttribute
            break
        }
    }

    // Update attribute
    if iIndexSourceItemFound == -1 {
        *aSliceDestination = append(*aSliceDestination, oSliceSourceItem)
    }
}
}

正如您所看到的,唯一的区别是函数参数的结构类型。

所以这是我的问题:有没有办法将这两个功能合并为一个?

我尝试过使用接口,但我无法理解......

提前感谢所有答案:)

干杯

修改

我已经实现了回答,但我收到了错误。这就是我所做的:

type Request struct {
    Headers         []RequestObject
}

type RequestObject {
    Key string
}

type Keyer interface {
    GetKey() string
}

func (oRequestObject RequestObject) GetKey() string {
    return oRequestObject.Key
}

func mergeKeyers(aDst *[]Keyer, aSrc []Keyer) {
    // Logic
}

func test() {
    // rDst and rSrc are Request struct
    mergeKeyers(&rDst.Headers, rSrc.Headers)
}

执行 test()时,我遇到以下错误:

cannot use &rDst.Headers (type *[]RequestObject) as type *[]Keyer in argument to mergeKeyers
cannot use rSrc.Headers (type []RequestObject) as type []Keyer in argument to mergeKeyers

知道为什么吗?

1 个答案:

答案 0 :(得分:4)

定义界面:

type Keyer interface {
    Key() int // or whatever type the Key field has
}

然后在两种类型上实现接口:

func (r RequestObject) Key() int {
    return r.Key
}

func (r ResponseObject) Key() int {
    return r.Key
}

并重写你的函数来接受这个接口(而不是使用匈牙利表示法和无休止的长变量名):

func mergeKeyers(dst *[]Keyer, src []Keyer) {
    for _, s := range src {
        f := -1
        for i, d := range *dst {
            if s.Key() == d.Key() {
                f = i
                break
            }
        }
        if f == -1 {
            *dst = append(*dst, s)
        }
    }
}

另外,请考虑Dave C的评论:

  

你有一个O(n×m)算法,你可以使用O(n + m)算法。

我会让您以这种方式优化代码。

编辑以解决您的第二个问题:

类型*[]RequestObject*[]Keyer是不同的,不可互换。您需要做的是将您的RequestObjects切片转换为Keyers。

这就像迭代[]RequestObject一样简单,并将每个条目分配给类型为[]Keyer的值的新条目。

另见这些答案: