字典存储[key,value]对,Go提供了非常方便的实现,内置的map类型。
ItemDictionary
1. 目标
dict := ValueDictionary{}
Set()
Delete()
Has()
Get()
Clear()
Size()
Keys()
Values()
2. 实现
package dict
import (
"github.com/cheekybits/genny/generic"
"sync"
)
type Key generic.Type
type Value generic.Type
type ValueDictionary struct {
data map[Key]Value
mux sync.RWMutex
}
func (s *ValueDictionary)Set(key Key, value Value) {
if s.data == nil{
s.data = map[Key]Value{}
}
s.mux.Lock()
defer s.mux.Unlock()
s.data[key] = value
}
func (s *ValueDictionary)Delete(key Key) bool{
s.mux.Lock()
defer s.mux.Unlock()
_,ok := s.data[key]
if ok {
delete(s.data, key)
}
return ok
}
func (s *ValueDictionary)Has(key Key) bool{
s.mux.RLock()
s.mux.RUnlock()
_,result := s.data[key]
return result
}
func (s *ValueDictionary)Get(key Key) Value{
s.mux.RLock()
s.mux.RUnlock()
result,_ := s.data[key]
return result
}
func (s *ValueDictionary)Clear(){
s.mux.Lock()
defer s.mux.Unlock()
s.data = map[Key]Value{}
}
func (s *ValueDictionary)Size() int{
return len(s.data)
}
func (s *ValueDictionary)Keys() []Key{
s.mux.RLock()
s.mux.RUnlock()
keys := make([] Key,len(s.data))
for k := range s.data{
keys = append(keys, k)
}
return keys
}
func (s *ValueDictionary)Values() []Value{
s.mux.RLock()
s.mux.RUnlock()
values := make([] Value,len(s.data))
for _, v := range s.data{
values = append(values, v)
}
return values
}
3. 测试
测试代码描述如何使用上面定义的字典。我们不会直接和底层map进行交互,但如何Go没有提供map类型,需要另外的实现。
package dict
import (
"fmt"
"testing"
)
func TestValueDictionary_Set(t *testing.T) {
dict := ValueDictionary{}
dict.Set("1",1)
dict.Set("2",2)
dict.Set("3",3)
dict.Set("4",4)
fmt.Println("size:",dict.Size())
fmt.Println("1:",dict.Get("1"))
dict.Delete("1")
fmt.Println("keys",dict.Keys())
fmt.Println("values",dict.Values())
fmt.Println("has 2",dict.Has("2"))
fmt.Println("del 2",dict.Delete("2"))
fmt.Println("size:",dict.Size())
dict.Clear()
fmt.Println("size:",dict.Size())
}
我们可以通过下面命令生成具体类型字典:
genny -in ItemDictionary.go -out dictionary-string-int.go gen "Key=string Value=int"
4. 总结
本文基于map实现了字典数据类型,采用泛型方式,支持并发安全。