在我们之前的一个例子中,我们创建了一个函数,可以从Go中的一个片断中删除重复的值。然而,这个函数需要在每次片断的类型不同时重新实现。因此,如果我们有[]int 和[]string 分片,而我们想删除其中的重复值,到目前为止,我们需要两个函数:uniqueString() 和uniqueInt() 。但随着Go 1.18中泛型函数的发布,这不再是必要的了。我们可以编写一个单一的函数,它可以在任何值满足 comparable约束的任何片断。
package main
import "fmt"
func unique[T comparable](s []T) []T {
inResult := make(map[T]bool)
var result []T
for _, str := range s {
if _, ok := inResult[str]; !ok {
inResult[str] = true
result = append(result, str)
}
}
return result
}
type FruitRank struct {
Fruit string
Rank uint64
}
func main() {
fmt.Println(unique([]string{"abc", "cde", "efg", "efg", "abc", "cde"}))
fmt.Println(unique([]int{1, 1, 2, 2, 3, 3, 4}))
fruits := []FruitRank{
{
Fruit: "Strawberry",
Rank: 1,
},
{
Fruit: "Raspberry",
Rank: 2,
},
{
Fruit: "Blueberry",
Rank: 3,
},
{
Fruit: "Blueberry",
Rank: 3,
},
{
Fruit: "Strawberry",
Rank: 1,
},
}
fmt.Println(unique(fruits))
}
输出
[abc cde efg]
[1 2 3 4]
[{Strawberry 1} {Raspberry 2} {Blueberry 3}]
该函数与非泛型版本的区别仅在于它使用了一个类型参数T ,并带有 comparable约束。这是一个内置的约束,描述了任何可以使用== 和!= 操作符的类型。
我们创建的unique() 函数是一个通用的重复删除函数,正如你在例子的输出中所看到的,它对任何comparable 分片,如[]string,[]int, 或定义的struct 分片都有效。