利用go的interface实现的有锁Set
package main
import (
"fmt"
"sync"
)
type Set struct {
m map[interface{}]bool
sync.RWMutex
}
func New() *Set {
return &Set{
m: map[interface{}]bool{},
}
}
func (s *Set) Add(item interface{}) {
s.Lock()
defer s.Unlock()
s.m[item] = true
}
func (s *Set) Remove(item interface{}) {
s.Lock()
defer s.Unlock()
delete(s.m, item)
}
func (s *Set) Contains(item interface{}) bool{
s.RLock()
defer s.RUnlock()
_,ok := s.m[item]
return ok
}
func (s *Set) Len() int {
return len(s.List())
}
func (s *Set) Clear() {
s.Lock()
defer s.Unlock()
s.m = map[interface{}]bool{}
}
func (s *Set) IsEmpty() bool {
s.RLock()
defer s.RUnlock()
if s.Len() == 0 {
return true
}
return false
}
func (s *Set) List() []interface{} {
s.RLock()
defer s.RUnlock()
list := []interface{}{}
for k,_ := range s.m {
list = append(list, k)
}
return list
}
func (s *Set) Diff(t *Set) []interface{} {
sDiff := []interface{}{}
for sk := range s.m {
if _, ok := t.m[sk]; !ok {
sDiff = append(sDiff, sk)
}
}
return sDiff
}
func main() {
s := New()
s.Add(1)
s.Add(2)
s.Add(1)
if s.IsEmpty() {
fmt.Println("0 item")
}
s.Add(1)
s.Add(2)
s.Add(3)
s.Add("hello")
if s.Contains(2) {
fmt.Println("2 does exist")
}
s.Remove(2)
s.Remove(3)
s.Add(4)
s.Add("sky")
fmt.Println("list of all items", s.List())
t := New()
t.Add(1)
t.Add(3)
t.Add("world")
fmt.Println(s.Diff(t))
}