版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a41888313/article/details/103234744
- deepCopy 可以完成map,slice,strcut以及相对应的指针类型的Copy
func deepCopy(dst, src reflect.Value) {
switch src.Kind() {
case reflect.Interface:
value := src.Elem()
if !value.IsValid() {
return
}
newValue := reflect.New(value.Type()).Elem()
deepCopy(newValue, value)
dst.Set(newValue)
case reflect.Ptr:
value := src.Elem()
if !value.IsValid() {
return
}
dst.Set(reflect.New(value.Type()))
deepCopy(dst.Elem(), value)
case reflect.Map:
dst.Set(reflect.MakeMap(src.Type()))
keys := src.MapKeys()
for _, key := range keys {
value := src.MapIndex(key)
newValue := reflect.New(value.Type()).Elem()
deepCopy(newValue, value)
dst.SetMapIndex(key, newValue)
}
case reflect.Slice:
dst.Set(reflect.MakeSlice(src.Type(), src.Len(), src.Cap()))
for i := 0; i < src.Len(); i {
deepCopy(dst.Index(i), src.Index(i))
}
case reflect.Struct:
typeSrc := src.Type()
for i := 0; i < src.NumField(); i {
value := src.Field(i)
tag := typeSrc.Field(i).Tag
if value.CanSet() && tag.Get("deepcopy") != "-" {
deepCopy(dst.Field(i), value)
}
}
default:
dst.Set(src)
}
}
func DeepCopy(dst, src interface{}) {
typeDst := reflect.TypeOf(dst)
typeSrc := reflect.TypeOf(src)
if typeDst != typeSrc {
panic("DeepCopy: " typeDst.String() " != " typeSrc.String())
}
if typeSrc.Kind() != reflect.Ptr {
panic("DeepCopy: pass arguments by address")
}
valueDst := reflect.ValueOf(dst).Elem()
valueSrc := reflect.ValueOf(src).Elem()
if !valueDst.IsValid() || !valueSrc.IsValid() {
panic("DeepCopy: invalid arguments")
}
deepCopy(valueDst, valueSrc)
}
func DeepClone(v interface{}) interface{} {
dst := reflect.New(reflect.TypeOf(v)).Elem()
deepCopy(dst, reflect.ValueOf(v))
return dst.Interface()
}
- 协程安全的Map
package util
import (
"sync"
)
type Map struct {
sync.RWMutex
m map[interface{}]interface{}
}
func (m *Map) init() {
if m.m == nil {
m.m = make(map[interface{}]interface{})
}
}
func (m *Map) UnsafeGet(key interface{}) interface{} {
if m.m == nil {
return nil
} else {
return m.m[key]
}
}
func (m *Map) Get(key interface{}) interface{} {
m.RLock()
defer m.RUnlock()
return m.UnsafeGet(key)
}
func (m *Map) UnsafeSet(key interface{}, value interface{}) {
m.init()
m.m[key] = value
}
func (m *Map) Set(key interface{}, value interface{}) {
m.Lock()
defer m.Unlock()
m.UnsafeSet(key, value)
}
func (m *Map) TestAndSet(key interface{}, value interface{}) interface{} {
m.Lock()
defer m.Unlock()
m.init()
if v, ok := m.m[key]; ok {
return v
} else {
m.m[key] = value
return nil
}
}
func (m *Map) UnsafeDel(key interface{}) {
m.init()
delete(m.m, key)
}
func (m *Map) Del(key interface{}) {
m.Lock()
defer m.Unlock()
m.UnsafeDel(key)
}
func (m *Map) UnsafeLen() int {
if m.m == nil {
return 0
} else {
return len(m.m)
}
}
func (m *Map) Len() int {
m.RLock()
defer m.RUnlock()
return m.UnsafeLen()
}
func (m *Map) UnsafeRange(f func(interface{}, interface{})) {
if m.m == nil {
return
}
for k, v := range m.m {
f(k, v)
}
}
func (m *Map) RLockRange(f func(interface{}, interface{})) {
m.RLock()
defer m.RUnlock()
m.UnsafeRange(f)
}
func (m *Map) LockRange(f func(interface{}, interface{})) {
m.Lock()
defer m.Unlock()
m.UnsafeRange(f)
}
参考:github.com/name5566/leaf