增加任意数据类型之间的转换 && 使用锁实现并发安全的普通map
This commit is contained in:
		
							
								
								
									
										20
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| # Created by .ignore support plugin (hsz.mobi) | ||||
| ### Go template | ||||
| # Binaries for programs and plugins | ||||
| *.exe | ||||
| *.exe~ | ||||
| *.dll | ||||
| *.so | ||||
| *.dylib | ||||
|  | ||||
| # Test binary, built with `go test -c` | ||||
| *.test | ||||
|  | ||||
| # Output of the go coverage tool, specifically when used with LiteIDE | ||||
| *.out | ||||
|  | ||||
| # Dependency directories (remove the comment below to include it) | ||||
| # vendor/ | ||||
| .idea | ||||
| .vscode | ||||
|  | ||||
							
								
								
									
										393
									
								
								convert/convert.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								convert/convert.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,393 @@ | ||||
| // Package convert ... | ||||
| // | ||||
| // Description : 任意类型之间的相互转换 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 2021-02-23 10:23 下午 | ||||
| package convert | ||||
|  | ||||
| /* | ||||
|    Desc : 在处理一些参数的时候,可能需要将参数转换为各种类型,这里实现一个通用的转换函数,实现各种类型之间的相互转换。 | ||||
|  | ||||
|     当然,如果源数据格式和目标数据类型不一致,是会返回错误的。例如将字符串“一二三”转换为数值类型则会报错,而将字符串“123”转换为数值类型则OK。 | ||||
|  | ||||
|     这段代码实际抄自go自带的“database/sql”库,只是源代码作为内部函数无法在外面调用,可以单独把需要的功能拎出来使用: | ||||
|  | ||||
|     代码中有一个Scaner接口,可以自行实现,然后通过"convertAssign()"函数,作为dst参数传入。 | ||||
|  | ||||
|    Author : zhangdeman001@ke.com<张德满> | ||||
|  | ||||
| */ | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // RawBytes is a byte slice that holds a reference to memory owned by | ||||
| // the database itself. After a Scan into a RawBytes, the slice is only | ||||
| // valid until the next call to Next, Scan, or Close. | ||||
| type RawBytes []byte | ||||
|  | ||||
| var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error | ||||
|  | ||||
| // convertAssign copies to dest the value in src, converting it if possible. | ||||
| // An error is returned if the copy would result in loss of information. | ||||
| // dest should be a pointer type. | ||||
| func ConvertAssign(dest, src interface{}) error { | ||||
| 	// Common cases, without reflect. | ||||
| 	switch s := src.(type) { | ||||
| 	case string: | ||||
| 		switch d := dest.(type) { | ||||
| 		case *string: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = s | ||||
| 			return nil | ||||
| 		case *[]byte: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = []byte(s) | ||||
| 			return nil | ||||
| 		case *RawBytes: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = append((*d)[:0], s...) | ||||
| 			return nil | ||||
| 		} | ||||
| 	case []byte: | ||||
| 		switch d := dest.(type) { | ||||
| 		case *string: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = string(s) | ||||
| 			return nil | ||||
| 		case *interface{}: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = cloneBytes(s) | ||||
| 			return nil | ||||
| 		case *[]byte: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = cloneBytes(s) | ||||
| 			return nil | ||||
| 		case *RawBytes: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = s | ||||
| 			return nil | ||||
| 		} | ||||
| 	case time.Time: | ||||
| 		switch d := dest.(type) { | ||||
| 		case *time.Time: | ||||
| 			*d = s | ||||
| 			return nil | ||||
| 		case *string: | ||||
| 			*d = s.Format(time.RFC3339Nano) | ||||
| 			return nil | ||||
| 		case *[]byte: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = []byte(s.Format(time.RFC3339Nano)) | ||||
| 			return nil | ||||
| 		case *RawBytes: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = s.AppendFormat((*d)[:0], time.RFC3339Nano) | ||||
| 			return nil | ||||
| 		} | ||||
| 	case nil: | ||||
| 		switch d := dest.(type) { | ||||
| 		case *interface{}: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = nil | ||||
| 			return nil | ||||
| 		case *[]byte: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = nil | ||||
| 			return nil | ||||
| 		case *RawBytes: | ||||
| 			if d == nil { | ||||
| 				return errNilPtr | ||||
| 			} | ||||
| 			*d = nil | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var sv reflect.Value | ||||
|  | ||||
| 	switch d := dest.(type) { | ||||
| 	case *string: | ||||
| 		sv = reflect.ValueOf(src) | ||||
| 		switch sv.Kind() { | ||||
| 		case reflect.Bool, | ||||
| 			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||
| 			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, | ||||
| 			reflect.Float32, reflect.Float64: | ||||
| 			*d = asString(src) | ||||
| 			return nil | ||||
| 		} | ||||
| 	case *[]byte: | ||||
| 		sv = reflect.ValueOf(src) | ||||
| 		if b, ok := asBytes(nil, sv); ok { | ||||
| 			*d = b | ||||
| 			return nil | ||||
| 		} | ||||
| 	case *RawBytes: | ||||
| 		sv = reflect.ValueOf(src) | ||||
| 		if b, ok := asBytes([]byte(*d)[:0], sv); ok { | ||||
| 			*d = RawBytes(b) | ||||
| 			return nil | ||||
| 		} | ||||
| 	case *bool: | ||||
| 		bv, err := Bool.ConvertValue(src) | ||||
| 		if err == nil { | ||||
| 			*d = bv.(bool) | ||||
| 		} | ||||
| 		return err | ||||
| 	case *interface{}: | ||||
| 		*d = src | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if scanner, ok := dest.(Scanner); ok { | ||||
| 		return scanner.Scan(src) | ||||
| 	} | ||||
|  | ||||
| 	dpv := reflect.ValueOf(dest) | ||||
| 	if dpv.Kind() != reflect.Ptr { | ||||
| 		return errors.New("destination not a pointer") | ||||
| 	} | ||||
| 	if dpv.IsNil() { | ||||
| 		return errNilPtr | ||||
| 	} | ||||
|  | ||||
| 	if !sv.IsValid() { | ||||
| 		sv = reflect.ValueOf(src) | ||||
| 	} | ||||
|  | ||||
| 	dv := reflect.Indirect(dpv) | ||||
| 	if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { | ||||
| 		switch b := src.(type) { | ||||
| 		case []byte: | ||||
| 			dv.Set(reflect.ValueOf(cloneBytes(b))) | ||||
| 		default: | ||||
| 			dv.Set(sv) | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { | ||||
| 		dv.Set(sv.Convert(dv.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// The following conversions use a string value as an intermediate representation | ||||
| 	// to convert between various numeric types. | ||||
| 	// | ||||
| 	// This also allows scanning into user defined types such as "type Int int64". | ||||
| 	// For symmetry, also check for string destination types. | ||||
| 	switch dv.Kind() { | ||||
| 	case reflect.Ptr: | ||||
| 		if src == nil { | ||||
| 			dv.Set(reflect.Zero(dv.Type())) | ||||
| 			return nil | ||||
| 		} | ||||
| 		dv.Set(reflect.New(dv.Type().Elem())) | ||||
| 		return ConvertAssign(dv.Interface(), src) | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		s := asString(src) | ||||
| 		i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) | ||||
| 		if err != nil { | ||||
| 			err = strconvErr(err) | ||||
| 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||
| 		} | ||||
| 		dv.SetInt(i64) | ||||
| 		return nil | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		s := asString(src) | ||||
| 		u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) | ||||
| 		if err != nil { | ||||
| 			err = strconvErr(err) | ||||
| 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||
| 		} | ||||
| 		dv.SetUint(u64) | ||||
| 		return nil | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		s := asString(src) | ||||
| 		f64, err := strconv.ParseFloat(s, dv.Type().Bits()) | ||||
| 		if err != nil { | ||||
| 			err = strconvErr(err) | ||||
| 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||
| 		} | ||||
| 		dv.SetFloat(f64) | ||||
| 		return nil | ||||
| 	case reflect.String: | ||||
| 		switch v := src.(type) { | ||||
| 		case string: | ||||
| 			dv.SetString(v) | ||||
| 			return nil | ||||
| 		case []byte: | ||||
| 			dv.SetString(string(v)) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) | ||||
| } | ||||
|  | ||||
| func strconvErr(err error) error { | ||||
| 	if ne, ok := err.(*strconv.NumError); ok { | ||||
| 		return ne.Err | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func cloneBytes(b []byte) []byte { | ||||
| 	if b == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	c := make([]byte, len(b)) | ||||
| 	copy(c, b) | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func ToString(src interface{}) string { | ||||
| 	return asString(src) | ||||
| } | ||||
|  | ||||
| func asString(src interface{}) string { | ||||
| 	switch v := src.(type) { | ||||
| 	case string: | ||||
| 		return v | ||||
| 	case []byte: | ||||
| 		return string(v) | ||||
| 	} | ||||
| 	rv := reflect.ValueOf(src) | ||||
| 	switch rv.Kind() { | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		return strconv.FormatInt(rv.Int(), 10) | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		return strconv.FormatUint(rv.Uint(), 10) | ||||
| 	case reflect.Float64: | ||||
| 		return strconv.FormatFloat(rv.Float(), 'g', -1, 64) | ||||
| 	case reflect.Float32: | ||||
| 		return strconv.FormatFloat(rv.Float(), 'g', -1, 32) | ||||
| 	case reflect.Bool: | ||||
| 		return strconv.FormatBool(rv.Bool()) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%v", src) | ||||
| } | ||||
|  | ||||
| func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { | ||||
| 	switch rv.Kind() { | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		return strconv.AppendInt(buf, rv.Int(), 10), true | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		return strconv.AppendUint(buf, rv.Uint(), 10), true | ||||
| 	case reflect.Float32: | ||||
| 		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true | ||||
| 	case reflect.Float64: | ||||
| 		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true | ||||
| 	case reflect.Bool: | ||||
| 		return strconv.AppendBool(buf, rv.Bool()), true | ||||
| 	case reflect.String: | ||||
| 		s := rv.String() | ||||
| 		return append(buf, s...), true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Value is a value that drivers must be able to handle. | ||||
| // It is either nil, a type handled by a database driver's NamedValueChecker | ||||
| // interface, or an instance of one of these types: | ||||
| // | ||||
| //   int64 | ||||
| //   float64 | ||||
| //   bool | ||||
| //   []byte | ||||
| //   string | ||||
| //   time.Time | ||||
| type Value interface{} | ||||
|  | ||||
| type boolType struct{} | ||||
|  | ||||
| var Bool boolType | ||||
|  | ||||
| func (boolType) String() string { return "Bool" } | ||||
| func (boolType) ConvertValue(src interface{}) (Value, error) { | ||||
| 	switch s := src.(type) { | ||||
| 	case bool: | ||||
| 		return s, nil | ||||
| 	case string: | ||||
| 		b, err := strconv.ParseBool(s) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) | ||||
| 		} | ||||
| 		return b, nil | ||||
| 	case []byte: | ||||
| 		b, err := strconv.ParseBool(string(s)) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) | ||||
| 		} | ||||
| 		return b, nil | ||||
| 	} | ||||
|  | ||||
| 	sv := reflect.ValueOf(src) | ||||
| 	switch sv.Kind() { | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		iv := sv.Int() | ||||
| 		if iv == 1 || iv == 0 { | ||||
| 			return iv == 1, nil | ||||
| 		} | ||||
| 		return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", iv) | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		uv := sv.Uint() | ||||
| 		if uv == 1 || uv == 0 { | ||||
| 			return uv == 1, nil | ||||
| 		} | ||||
| 		return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", uv) | ||||
| 	} | ||||
|  | ||||
| 	return nil, fmt.Errorf("sql/driver: couldn't convert %v (%T) into type bool", src, src) | ||||
| } | ||||
|  | ||||
| type Scanner interface { | ||||
| 	// Scan assigns a value from a database driver. | ||||
| 	// | ||||
| 	// The src value will be of one of the following types: | ||||
| 	// | ||||
| 	//    int64 | ||||
| 	//    float64 | ||||
| 	//    bool | ||||
| 	//    []byte | ||||
| 	//    string | ||||
| 	//    time.Time | ||||
| 	//    nil - for NULL values | ||||
| 	// | ||||
| 	// An error should be returned if the value cannot be stored | ||||
| 	// without loss of information. | ||||
| 	// | ||||
| 	// Reference types such as []byte are only valid until the next call to Scan | ||||
| 	// and should not be retained. Their underlying memory is owned by the driver. | ||||
| 	// If retention is necessary, copy their values before the next call to Scan. | ||||
| 	Scan(src interface{}) error | ||||
| } | ||||
							
								
								
									
										36
									
								
								easymap/abstruct.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								easymap/abstruct.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| // Package easymap... | ||||
| // | ||||
| // Description : easymap... | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 2021-02-23 9:55 下午 | ||||
| package easymap | ||||
|  | ||||
| // EasyMap 约束各种数据接口的实现 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 9:56 下午 2021/2/23 | ||||
| type EasyMap interface { | ||||
| 	Get(key interface{}) (interface{}, error) | ||||
| 	GetWithReceiver(key interface{}, dest interface{}) error | ||||
| 	GetUint(key interface{}) (uint, error) | ||||
| 	GetUint8(key interface{}) (uint8, error) | ||||
| 	GetUint16(key interface{}) (uint16, error) | ||||
| 	GetUint32(key interface{}) (uint32, error) | ||||
| 	GetUint64(key interface{}) (uint64, error) | ||||
| 	GetInt(key interface{}) (int, error) | ||||
| 	GetInt8(key interface{}) (int8, error) | ||||
| 	GetInt16(key interface{}) (int16, error) | ||||
| 	GetInt32(key interface{}) (int32, error) | ||||
| 	GetInt64(key interface{}) (int64, error) | ||||
| 	GetFloat32(key interface{}) (float32, error) | ||||
| 	GetFloat64(key interface{}) (float64, error) | ||||
| 	GetBool(key interface{}) (bool, error) | ||||
| 	GetString(key interface{}) (string, error) | ||||
| 	Set(key interface{}, value interface{}) | ||||
| 	Del(key interface{}) | ||||
| 	Exist(key interface{}) bool | ||||
| 	GetAll() map[interface{}]interface{} | ||||
| } | ||||
							
								
								
									
										28
									
								
								easymap/error.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								easymap/error.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| // Package easymap... | ||||
| // | ||||
| // Description : easymap... | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 2021-02-23 10:15 下午 | ||||
| package easymap | ||||
|  | ||||
| import "github.com/pkg/errors" | ||||
|  | ||||
| // keyNotFound key 不存在 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:17 下午 2021/2/23 | ||||
| func keyNotFound(key interface{}) error { | ||||
| 	return errors.Errorf("%v 未找到", key) | ||||
| } | ||||
|  | ||||
| // convertFail 数据类型妆换失败 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:28 下午 2021/2/23 | ||||
| func convertFail(err error) error { | ||||
| 	return errors.Wrapf(err, "数据类型转换失败") | ||||
| } | ||||
							
								
								
									
										273
									
								
								easymap/normal_map.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								easymap/normal_map.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,273 @@ | ||||
| // Package easymap ... | ||||
| // | ||||
| // Description : 普通的的map,增加锁支持 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 2021-02-23 10:03 下午 | ||||
| package easymap | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/go-developer/gopkg/convert" | ||||
| ) | ||||
|  | ||||
| // NewNormal 获取map实例 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:07 下午 2021/2/23 | ||||
| func NewNormal(withLock bool) EasyMap { | ||||
| 	em := &normal{ | ||||
| 		data:     make(map[interface{}]interface{}), | ||||
| 		withLock: withLock, | ||||
| 	} | ||||
| 	if withLock { | ||||
| 		em.lock = &sync.RWMutex{} | ||||
| 	} | ||||
| 	return em | ||||
| } | ||||
|  | ||||
| // normal 普通map,内部可以加锁 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:03 下午 2021/2/23 | ||||
| type normal struct { | ||||
| 	data     map[interface{}]interface{} | ||||
| 	withLock bool | ||||
| 	lock     *sync.RWMutex | ||||
| } | ||||
|  | ||||
| func (n *normal) Get(key interface{}) (interface{}, error) { | ||||
| 	if !n.Exist(key) { | ||||
| 		return nil, keyNotFound(key) | ||||
| 	} | ||||
| 	n.RLock() | ||||
| 	defer n.RUnlock() | ||||
| 	return n.data[key], nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetWithReceiver(key interface{}, dest interface{}) error { | ||||
| 	var ( | ||||
| 		val interface{} | ||||
| 		err error | ||||
| 	) | ||||
| 	if val, err = n.Get(key); nil != err { | ||||
| 		return err | ||||
| 	} | ||||
| 	return convertFail(convert.ConvertAssign(dest, val)) | ||||
| } | ||||
|  | ||||
| func (n *normal) GetUint(key interface{}) (uint, error) { | ||||
| 	var ( | ||||
| 		result uint | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetUint8(key interface{}) (uint8, error) { | ||||
| 	var ( | ||||
| 		result uint8 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetUint16(key interface{}) (uint16, error) { | ||||
| 	var ( | ||||
| 		result uint16 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetUint32(key interface{}) (uint32, error) { | ||||
| 	var ( | ||||
| 		result uint32 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetUint64(key interface{}) (uint64, error) { | ||||
| 	var ( | ||||
| 		result uint64 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetInt(key interface{}) (int, error) { | ||||
| 	var ( | ||||
| 		result int | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetInt8(key interface{}) (int8, error) { | ||||
| 	var ( | ||||
| 		result int8 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetInt16(key interface{}) (int16, error) { | ||||
| 	var ( | ||||
| 		result int16 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetInt32(key interface{}) (int32, error) { | ||||
| 	var ( | ||||
| 		result int32 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetInt64(key interface{}) (int64, error) { | ||||
| 	var ( | ||||
| 		result int64 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetFloat32(key interface{}) (float32, error) { | ||||
| 	var ( | ||||
| 		result float32 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetFloat64(key interface{}) (float64, error) { | ||||
| 	var ( | ||||
| 		result float64 | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetBool(key interface{}) (bool, error) { | ||||
| 	var ( | ||||
| 		result bool | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) GetString(key interface{}) (string, error) { | ||||
| 	var ( | ||||
| 		result string | ||||
| 		err    error | ||||
| 	) | ||||
| 	if err = n.GetWithReceiver(key, &result); nil != err { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (n *normal) Set(key interface{}, value interface{}) { | ||||
| 	n.Lock() | ||||
| 	defer n.Unlock() | ||||
| 	n.data[key] = value | ||||
| } | ||||
|  | ||||
| func (n *normal) Del(key interface{}) { | ||||
| 	n.Lock() | ||||
| 	defer n.Unlock() | ||||
| 	delete(n.data, key) | ||||
| } | ||||
|  | ||||
| func (n *normal) Exist(key interface{}) bool { | ||||
| 	n.RLock() | ||||
| 	defer n.RUnlock() | ||||
| 	_, exist := n.data[key] | ||||
| 	return exist | ||||
| } | ||||
|  | ||||
| // GetAll 读取全部数据使用的是原始数据深拷贝,避免获取到全部数据之后,直接读取导致并发读写 | ||||
| // | ||||
| // Author : go_developer@163.com<张德满> | ||||
| // | ||||
| // Date : 10:36 下午 2021/2/23 | ||||
| func (n *normal) GetAll() map[interface{}]interface{} { | ||||
| 	result := make(map[interface{}]interface{}) | ||||
| 	n.lock.RLock() | ||||
| 	defer n.lock.RUnlock() | ||||
| 	for key, val := range n.data { | ||||
| 		result[key] = val | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (n *normal) RLock() { | ||||
| 	if n.withLock { | ||||
| 		n.lock.RLock() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (n *normal) RUnlock() { | ||||
| 	if n.withLock { | ||||
| 		n.lock.RUnlock() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (n *normal) Lock() { | ||||
| 	if n.withLock { | ||||
| 		n.lock.Lock() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (n *normal) Unlock() { | ||||
| 	if n.withLock { | ||||
| 		n.lock.Unlock() | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| module github.com/go-developer/gopkg | ||||
|  | ||||
| go 1.15 | ||||
|  | ||||
| require github.com/pkg/errors v0.9.1 | ||||
		Reference in New Issue
	
	Block a user