Go Set实现

利用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))
}