新到Go语言的伙伴当认识到Go没有Set这种存储唯一值的内置数据结构。但是利用Map也不难实现。由于Go的泛型没有像一样Java一样完善,因此你就得对每种类型单独实现Set来拒绝重复,这样显得有些无聊。
那么我们看一下以下解决方式:
使用空结构体 struct{} 可以节省内存,一般作为占位符使用,表明这里并不需要一个值
fmt.Println(unsafe.Sizeof(struct{}{})) // 0
那么我们把空结构体的这个特性运用到实现Set上:
// UniqStr 返回一个切片,该切片包含传入的字符串切片中去重的结果。
func UniqStr(col []string) []string {
m := map[string]struct{}{}
for _, v := range col {
if _, ok := m[v]; !ok {
m[v] = struct{}{}
}
}
list := make([]string, len(m))
i := 0
for v := range m {
list[i] = v
i++
}
return list
}
或者也可以提前声明为别名:
type Set map[string]struct{}
type Set map[string]struct{}func main(){
set := make(Set)
for _, item := range []string{"A", "A", "B", "C"} {
set[item] = struct{}{}
}
fmt.Println(len(set)) // 3
if _, ok := set["A"]; ok {
fmt.Println("A exists") // A exists
}
}
空结构体也可以用在信道(channel)通信时我们只需要一个信号,但不需要传递值的情况:
func main() {
ch := make(chan struct{}, 1)
go func() {
<-ch // do something
}()
ch <- struct{}{}
// ...}