mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 04:07:47 +08:00
comments update
This commit is contained in:
parent
7cc0c7a1cc
commit
8138215597
@ -6,9 +6,9 @@
|
||||
|
||||
// Package gredis provides convenient client for redis server.
|
||||
//
|
||||
// Redis客户端.
|
||||
// Redis中文手册请参考:http://redisdoc.com/
|
||||
// Redis官方命令请参考:https://redis.io/commands
|
||||
// Redis Client.
|
||||
// Redis Commands Official: https://redis.io/commands
|
||||
// Redis Chinese Documentation: http://redisdoc.com/
|
||||
package gredis
|
||||
|
||||
import (
|
||||
@ -23,44 +23,42 @@ const (
|
||||
gDEFAULT_POOL_MAX_LIFE_TIME = 60 * time.Second
|
||||
)
|
||||
|
||||
// Redis客户端(管理连接池)
|
||||
// Redis client.
|
||||
type Redis struct {
|
||||
pool *redis.Pool // 底层连接池
|
||||
group string // 配置分组
|
||||
config Config // 配置对象
|
||||
pool *redis.Pool // Underlying connection pool.
|
||||
group string // Configuration group.
|
||||
config Config // Configuration.
|
||||
}
|
||||
|
||||
// Redis连接对象(连接池中的单个连接)
|
||||
// Redis connection.
|
||||
type Conn redis.Conn
|
||||
|
||||
// Redis服务端但节点连接配置信息
|
||||
// Redis configuration.
|
||||
type Config struct {
|
||||
Host string // 地址
|
||||
Port int // 端口
|
||||
Db int // 数据库
|
||||
Pass string // 授权密码
|
||||
MaxIdle int // 最大允许空闲存在的连接数(默认为0表示不存在闲置连接)
|
||||
MaxActive int // 最大连接数量限制(默认为0表示不限制)
|
||||
IdleTimeout time.Duration // 连接最大空闲时间(默认为60秒,不允许设置为0)
|
||||
MaxConnLifetime time.Duration // 连接最长存活时间(默认为60秒,不允许设置为0)
|
||||
Host string
|
||||
Port int
|
||||
Db int
|
||||
Pass string // Password for AUTH.
|
||||
MaxIdle int // Maximum number of connections allowed to be idle (default is 0 means no idle connection)
|
||||
MaxActive int // Maximum number of connections limit (default is 0 means no limit)
|
||||
IdleTimeout time.Duration // Maximum idle time for connection (default is 60 seconds, not allowed to be set to 0)
|
||||
MaxConnLifetime time.Duration // Maximum lifetime of the connection (default is 60 seconds, not allowed to be set to 0)
|
||||
}
|
||||
|
||||
// Redis链接池统计信息
|
||||
// Pool statistics.
|
||||
type PoolStats struct {
|
||||
redis.PoolStats
|
||||
}
|
||||
|
||||
var (
|
||||
// 单例对象Map
|
||||
// Instance map
|
||||
instances = gmap.NewStrAnyMap()
|
||||
// 连接池Map
|
||||
// Pool map.
|
||||
pools = gmap.NewStrAnyMap()
|
||||
)
|
||||
|
||||
// New creates a redis client object with given configuration.
|
||||
// Redis client maintains a connection pool automatically.
|
||||
//
|
||||
// 创建redis操作对象,底层根据配置信息公用的连接池(连接池单例)。
|
||||
func New(config Config) *Redis {
|
||||
if config.IdleTimeout == 0 {
|
||||
config.IdleTimeout = gDEFAULT_POOL_IDLE_TIMEOUT
|
||||
@ -79,20 +77,20 @@ func New(config Config) *Redis {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 密码设置
|
||||
// AUTH
|
||||
if len(config.Pass) > 0 {
|
||||
if _, err := c.Do("AUTH", config.Pass); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// 数据库设置
|
||||
// DB
|
||||
if _, err := c.Do("SELECT", config.Db); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
},
|
||||
// 在被应用从连接池中获取出来之后,用以测试连接是否可用,
|
||||
// 如果返回error那么关闭该连接对象重新创建新的连接。
|
||||
// After the conn is taken from the connection pool, to test if the connection is available,
|
||||
// If error is returned then it closes the connection object and recreate a new connection.
|
||||
TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
_, err := c.Do("PING")
|
||||
return err
|
||||
@ -104,9 +102,7 @@ func New(config Config) *Redis {
|
||||
|
||||
// Instance returns an instance of redis client with specified group.
|
||||
// The <group> param is unnecessary, if <group> is not passed,
|
||||
// return redis instance with default group.
|
||||
//
|
||||
// 获取指定分组名称的Redis单例对象,底层根据配置信息公用的连接池(连接池单例)。
|
||||
// it returns a redis instance with default group.
|
||||
func Instance(name ...string) *Redis {
|
||||
group := DEFAULT_GROUP_NAME
|
||||
if len(name) > 0 {
|
||||
@ -128,73 +124,56 @@ func Instance(name ...string) *Redis {
|
||||
|
||||
// Close closes the redis connection pool,
|
||||
// it will release all connections reserved by this pool.
|
||||
// It always not necessary to call Close manually.
|
||||
//
|
||||
// 关闭redis管理对象,将会关闭底层的连接池。
|
||||
// 往往没必要手动调用,跟随进程销毁即可。
|
||||
// It is not necessary to call Close manually.
|
||||
func (r *Redis) Close() error {
|
||||
if r.group != "" {
|
||||
// 如果是单例对象,那么需要从单例对象Map中删除
|
||||
// If it is an instance object, it needs to remove it from the instance Map.
|
||||
instances.Remove(r.group)
|
||||
}
|
||||
pools.Remove(fmt.Sprintf("%v", r.config))
|
||||
return r.pool.Close()
|
||||
}
|
||||
|
||||
// See GetConn.
|
||||
// Alias of GetConn, see GetConn.
|
||||
func (r *Redis) Conn() Conn {
|
||||
return r.GetConn()
|
||||
}
|
||||
|
||||
// GetConn returns a raw connection object,
|
||||
// which expose more methods communication with server.
|
||||
// GetConn returns a raw underlying connection object,
|
||||
// which expose more methods to communicate with server.
|
||||
// **You should call Close function manually if you do not use this connection any further.**
|
||||
//
|
||||
// 获得一个原生的redis连接对象,用于自定义连接操作,
|
||||
// 但是需要注意的是如果不再使用该连接对象时,需要手动Close连接,否则会造成连接数超限。
|
||||
func (r *Redis) GetConn() Conn {
|
||||
return r.pool.Get().(Conn)
|
||||
}
|
||||
|
||||
// SetMaxIdle sets the MaxIdle attribute of the connection pool.
|
||||
//
|
||||
// 设置属性 - MaxIdle
|
||||
func (r *Redis) SetMaxIdle(value int) {
|
||||
r.pool.MaxIdle = value
|
||||
}
|
||||
|
||||
// SetMaxIdle sets the MaxActive attribute of the connection pool.
|
||||
//
|
||||
// 设置属性 - MaxActive
|
||||
// SetMaxActive sets the MaxActive attribute of the connection pool.
|
||||
func (r *Redis) SetMaxActive(value int) {
|
||||
r.pool.MaxActive = value
|
||||
}
|
||||
|
||||
// SetMaxIdle sets the IdleTimeout attribute of the connection pool.
|
||||
//
|
||||
// 设置属性 - IdleTimeout
|
||||
// SetIdleTimeout sets the IdleTimeout attribute of the connection pool.
|
||||
func (r *Redis) SetIdleTimeout(value time.Duration) {
|
||||
r.pool.IdleTimeout = value
|
||||
}
|
||||
|
||||
// SetMaxIdle sets the MaxConnLifetime attribute of the connection pool.
|
||||
//
|
||||
// 设置属性 - MaxConnLifetime
|
||||
// SetMaxConnLifetime sets the MaxConnLifetime attribute of the connection pool.
|
||||
func (r *Redis) SetMaxConnLifetime(value time.Duration) {
|
||||
r.pool.MaxConnLifetime = value
|
||||
}
|
||||
|
||||
// Stats returns pool's statistics.
|
||||
//
|
||||
// 获取当前连接池统计信息。
|
||||
func (r *Redis) Stats() *PoolStats {
|
||||
return &PoolStats{r.pool.Stats()}
|
||||
}
|
||||
|
||||
// Do sends a command to the server and returns the received reply.
|
||||
// Do automatically get a connection from pool, and close it when reply received.
|
||||
//
|
||||
// 执行同步命令,自动从连接池中获取连接,使用完毕后关闭连接(丢回连接池),开发者不用自行Close.
|
||||
// It does not really "close" the connection, but drop it back to the connection pool.
|
||||
func (r *Redis) Do(command string, args ...interface{}) (interface{}, error) {
|
||||
conn := r.pool.Get()
|
||||
defer conn.Close()
|
||||
@ -203,8 +182,6 @@ func (r *Redis) Do(command string, args ...interface{}) (interface{}, error) {
|
||||
|
||||
// Deprecated.
|
||||
// Send writes the command to the client's output buffer.
|
||||
//
|
||||
// 执行异步命令 - Send
|
||||
func (r *Redis) Send(command string, args ...interface{}) error {
|
||||
conn := r.pool.Get()
|
||||
defer conn.Close()
|
||||
|
@ -32,7 +32,7 @@ const (
|
||||
type Config struct {
|
||||
name *gtype.String // Default configuration file name.
|
||||
paths *garray.StringArray // Searching path array.
|
||||
jsons *gmap.StrAnyMap // The pared JSON objects for configuration files.
|
||||
jsons *gmap.StrAnyMap // The pared JSON objects for configuration files.
|
||||
vc *gtype.Bool // Whether do violence check in value index searching.
|
||||
// It affects the performance when set true(false in default).
|
||||
}
|
||||
@ -146,7 +146,6 @@ func (c *Config) SetPath(path string) error {
|
||||
c.jsons.Clear()
|
||||
c.paths.Clear()
|
||||
c.paths.Append(realPath)
|
||||
//glog.Debug("[gcfg] SetPath:", realPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -230,7 +229,6 @@ func (c *Config) GetFilePath(file...string) (path string) {
|
||||
|
||||
// SetFileName sets the default configuration file name.
|
||||
func (c *Config) SetFileName(name string) {
|
||||
//glog.Debug("[gcfg] SetFileName:", name)
|
||||
c.name.Set(name)
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,11 @@ import (
|
||||
)
|
||||
|
||||
type Cron struct {
|
||||
idGen *gtype.Int64 // Used for unique name generation.
|
||||
status *gtype.Int // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed)
|
||||
idGen *gtype.Int64 // Used for unique name generation.
|
||||
status *gtype.Int // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed)
|
||||
entries *gmap.StrAnyMap // All timed task entries.
|
||||
logPath *gtype.String // Logging path(folder).
|
||||
logLevel *gtype.Int // Logging level.
|
||||
logPath *gtype.String // Logging path(folder).
|
||||
logLevel *gtype.Int // Logging level.
|
||||
}
|
||||
|
||||
// New returns a new Cron object with default settings.
|
||||
|
@ -4,7 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package gtest provides convenient test utils for unit testing.
|
||||
// Package gtest provides convenient test utilities for unit testing.
|
||||
package gtest
|
||||
|
||||
import (
|
||||
@ -111,8 +111,8 @@ func AssertGT(value, expect interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// See AssertGE.
|
||||
// Deprecated.
|
||||
// See AssertGE.
|
||||
func AssertGTE(value, expect interface{}) {
|
||||
AssertGE(value, expect)
|
||||
}
|
||||
@ -163,8 +163,8 @@ func AssertLT(value, expect interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// See AssertLE.
|
||||
// Deprecated.
|
||||
// See AssertLE.
|
||||
func AssertLTE(value, expect interface{}) {
|
||||
AssertLE(value, expect)
|
||||
}
|
||||
|
@ -5,9 +5,6 @@
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package gconv implements powerful and easy-to-use converting functionality for any types of variables.
|
||||
//
|
||||
// 类型转换,
|
||||
// 内部使用了bytes作为底层转换类型,效率很高。
|
||||
package gconv
|
||||
|
||||
import (
|
||||
@ -18,13 +15,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 转换为string类型的接口
|
||||
// Type assert api for String().
|
||||
type apiString interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
var (
|
||||
// 为空的字符串
|
||||
// Empty strings.
|
||||
emptyStringMap = map[string]struct{}{
|
||||
"" : struct {}{},
|
||||
"0" : struct {}{},
|
||||
@ -33,8 +30,10 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// 将变量i转换为字符串指定的类型t,非必须参数extraParams用以额外的参数传递
|
||||
func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
|
||||
|
||||
// Convert converts the variable <i> to the type <t>, the type <t> is specified by string.
|
||||
// The unnecessary parameter <params> is used for additional parameter passing.
|
||||
func Convert(i interface{}, t string, params...interface{}) interface{} {
|
||||
switch t {
|
||||
case "int": return Int(i)
|
||||
case "int8": return Int8(i)
|
||||
@ -54,18 +53,18 @@ func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
|
||||
case "[]int": return Ints(i)
|
||||
case "[]string": return Strings(i)
|
||||
case "time.Time":
|
||||
if len(extraParams) > 0 {
|
||||
return Time(i, String(extraParams[0]))
|
||||
if len(params) > 0 {
|
||||
return Time(i, String(params[0]))
|
||||
}
|
||||
return Time(i)
|
||||
case "gtime.Time":
|
||||
if len(extraParams) > 0 {
|
||||
return GTime(i, String(extraParams[0]))
|
||||
if len(params) > 0 {
|
||||
return GTime(i, String(params[0]))
|
||||
}
|
||||
return *GTime(i)
|
||||
case "*gtime.Time":
|
||||
if len(extraParams) > 0 {
|
||||
return GTime(i, String(extraParams[0]))
|
||||
if len(params) > 0 {
|
||||
return GTime(i, String(params[0]))
|
||||
}
|
||||
return GTime(i)
|
||||
case "time.Duration": return TimeDuration(i)
|
||||
@ -74,7 +73,7 @@ func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// 转换为二进制[]byte
|
||||
// Bytes converts <i> to []byte.
|
||||
func Bytes(i interface{}) []byte {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -87,7 +86,7 @@ func Bytes(i interface{}) []byte {
|
||||
}
|
||||
}
|
||||
|
||||
// 基础的字符串类型转换
|
||||
// String converts <i> to string.
|
||||
func String(i interface{}) string {
|
||||
if i == nil {
|
||||
return ""
|
||||
@ -110,17 +109,19 @@ func String(i interface{}) string {
|
||||
case []byte: return string(value)
|
||||
default:
|
||||
if f, ok := value.(apiString); ok {
|
||||
// 如果变量实现了String()接口,那么使用该接口执行转换
|
||||
// If the variable implements the String() interface,
|
||||
// then use that interface to perform the conversion
|
||||
return f.String()
|
||||
} else {
|
||||
// 默认使用json进行字符串转换
|
||||
// Finally we use json.Marshal to convert.
|
||||
jsonContent, _ := json.Marshal(value)
|
||||
return string(jsonContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//false: false, "", 0, "false", "off", empty slice/map
|
||||
// Bool converts <i> to bool.
|
||||
// It returns false if <i> is: false, "", 0, "false", "off", empty slice/map.
|
||||
func Bool(i interface{}) bool {
|
||||
if i == nil {
|
||||
return false
|
||||
@ -151,6 +152,7 @@ func Bool(i interface{}) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Int converts <i> to int.
|
||||
func Int(i interface{}) int {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -161,6 +163,7 @@ func Int(i interface{}) int {
|
||||
return int(Int64(i))
|
||||
}
|
||||
|
||||
// Int8 converts <i> to int8.
|
||||
func Int8(i interface{}) int8 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -171,6 +174,7 @@ func Int8(i interface{}) int8 {
|
||||
return int8(Int64(i))
|
||||
}
|
||||
|
||||
// Int16 converts <i> to int16.
|
||||
func Int16(i interface{}) int16 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -181,6 +185,7 @@ func Int16(i interface{}) int16 {
|
||||
return int16(Int64(i))
|
||||
}
|
||||
|
||||
// Int32 converts <i> to int32.
|
||||
func Int32(i interface{}) int32 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -191,6 +196,7 @@ func Int32(i interface{}) int32 {
|
||||
return int32(Int64(i))
|
||||
}
|
||||
|
||||
// Int64 converts <i> to int64.
|
||||
func Int64(i interface{}) int64 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -218,27 +224,28 @@ func Int64(i interface{}) int64 {
|
||||
return 0
|
||||
default:
|
||||
s := String(value)
|
||||
// 按照十六进制解析
|
||||
// Hexadecimal
|
||||
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
|
||||
if v, e := strconv.ParseInt(s[2 : ], 16, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
// 按照八进制解析
|
||||
// Octal
|
||||
if len(s) > 1 && s[0] == '0' {
|
||||
if v, e := strconv.ParseInt(s[1 : ], 8, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
// 按照十进制解析
|
||||
// Decimal
|
||||
if v, e := strconv.ParseInt(s, 10, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
// 按照浮点数解析
|
||||
// Float64
|
||||
return int64(Float64(value))
|
||||
}
|
||||
}
|
||||
|
||||
// Uint converts <i> to uint.
|
||||
func Uint(i interface{}) uint {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -249,6 +256,7 @@ func Uint(i interface{}) uint {
|
||||
return uint(Uint64(i))
|
||||
}
|
||||
|
||||
// Uint8 converts <i> to uint8.
|
||||
func Uint8(i interface{}) uint8 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -259,6 +267,7 @@ func Uint8(i interface{}) uint8 {
|
||||
return uint8(Uint64(i))
|
||||
}
|
||||
|
||||
// Uint16 converts <i> to uint16.
|
||||
func Uint16(i interface{}) uint16 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -269,6 +278,7 @@ func Uint16(i interface{}) uint16 {
|
||||
return uint16(Uint64(i))
|
||||
}
|
||||
|
||||
// Uint32 converts <i> to uint32.
|
||||
func Uint32(i interface{}) uint32 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -279,6 +289,7 @@ func Uint32(i interface{}) uint32 {
|
||||
return uint32(Uint64(i))
|
||||
}
|
||||
|
||||
// Uint64 converts <i> to uint64.
|
||||
func Uint64(i interface{}) uint64 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -303,27 +314,28 @@ func Uint64(i interface{}) uint64 {
|
||||
return 0
|
||||
default:
|
||||
s := String(value)
|
||||
// 按照十六进制解析
|
||||
// Hexadecimal
|
||||
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
|
||||
if v, e := strconv.ParseUint(s[2 : ], 16, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
// 按照八进制解析
|
||||
// Octal
|
||||
if len(s) > 1 && s[0] == '0' {
|
||||
if v, e := strconv.ParseUint(s[1 : ], 8, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
// 按照十进制解析
|
||||
// Decimal
|
||||
if v, e := strconv.ParseUint(s, 10, 64); e == nil {
|
||||
return v
|
||||
}
|
||||
// 按照浮点数解析
|
||||
// Float64
|
||||
return uint64(Float64(value))
|
||||
}
|
||||
}
|
||||
|
||||
// Float32 converts <i> to float32.
|
||||
func Float32 (i interface{}) float32 {
|
||||
if i == nil {
|
||||
return 0
|
||||
@ -335,6 +347,7 @@ func Float32 (i interface{}) float32 {
|
||||
return float32(v)
|
||||
}
|
||||
|
||||
// Float64 converts <i> to float64.
|
||||
func Float64 (i interface{}) float64 {
|
||||
if i == nil {
|
||||
return 0
|
||||
|
@ -13,9 +13,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 任意类型转换为 map[string]interface{} 类型,
|
||||
// 如果给定的输入参数i不是map类型,那么转换会失败,返回nil.
|
||||
// 当i为struct对象时,第二个参数noTagCheck表示不检测json标签,否则将会使用json tag作为map的键名。
|
||||
// Map converts any variable <i> to map[string]interface{}.
|
||||
// If the parameter <i> is not a map type, then the conversion will fail and returns nil.
|
||||
// If <i> is a struct object, the second parameter noTagCheck means that
|
||||
// the json tag is not detected,
|
||||
// otherwise the json tag will be used as the map key name.
|
||||
func Map(value interface{}, noTagCheck...bool) map[string]interface{} {
|
||||
if value == nil {
|
||||
return nil
|
||||
@ -23,7 +25,7 @@ func Map(value interface{}, noTagCheck...bool) map[string]interface{} {
|
||||
if r, ok := value.(map[string]interface{}); ok {
|
||||
return r
|
||||
} else {
|
||||
// 仅对常见的几种map组合进行断言,最后才会使用反射
|
||||
// Only assert the common combination type of maps, and finally use reflection.
|
||||
m := make(map[string]interface{})
|
||||
switch value.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
@ -84,11 +86,11 @@ func Map(value interface{}, noTagCheck...bool) map[string]interface{} {
|
||||
for k, v := range value.(map[uint]string) {
|
||||
m[String(k)] = v
|
||||
}
|
||||
// 不是常见类型,则使用反射
|
||||
// Not a common type, use reflection
|
||||
default:
|
||||
rv := reflect.ValueOf(value)
|
||||
kind := rv.Kind()
|
||||
// 如果是指针,那么需要转换到指针对应的数据项,以便识别真实的类型
|
||||
// If it is a pointer, we should find its real data type.
|
||||
if kind == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
kind = rv.Kind()
|
||||
@ -103,13 +105,14 @@ func Map(value interface{}, noTagCheck...bool) map[string]interface{} {
|
||||
rt := rv.Type()
|
||||
name := ""
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
// 只转换公开属性
|
||||
// Only convert the public attributes.
|
||||
fieldName := rt.Field(i).Name
|
||||
if !gstr.IsLetterUpper(fieldName[0]) {
|
||||
continue
|
||||
}
|
||||
name = ""
|
||||
// 检查tag, 支持gconv, json标签, 优先使用gconv
|
||||
// Tag check, supporting "gconv" and "json" tag,
|
||||
// "gconv" has the high priority to use.
|
||||
if len(noTagCheck) == 0 || !noTagCheck[0] {
|
||||
tag := rt.Field(i).Tag
|
||||
if name = tag.Get("gconv"); name == "" {
|
||||
@ -119,7 +122,7 @@ func Map(value interface{}, noTagCheck...bool) map[string]interface{} {
|
||||
if name == "" {
|
||||
name = strings.TrimSpace(fieldName)
|
||||
} else {
|
||||
// 支持标准库json特性: -, omitempty
|
||||
// Support json tag feature: -, omitempty
|
||||
name = strings.TrimSpace(name)
|
||||
if name == "-" {
|
||||
continue
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// 任意类型转换为[]int类型
|
||||
// Ints converts <i> to []int.
|
||||
func Ints(i interface{}) []int {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -84,7 +84,7 @@ func Ints(i interface{}) []int {
|
||||
}
|
||||
}
|
||||
|
||||
// 任意类型转换为[]string类型
|
||||
// Strings converts <i> to []string.
|
||||
func Strings(i interface{}) []string {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -157,7 +157,7 @@ func Strings(i interface{}) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// 将类型转换为[]float64类型
|
||||
// Strings converts <i> to []float64.
|
||||
func Floats(i interface{}) []float64 {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -230,7 +230,7 @@ func Floats(i interface{}) []float64 {
|
||||
}
|
||||
}
|
||||
|
||||
// 任意类型转换为[]interface{}类型
|
||||
// Interfaces converts <i> to []interface{}.
|
||||
func Interfaces(i interface{}) []interface{} {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -296,11 +296,11 @@ func Interfaces(i interface{}) []interface{} {
|
||||
for _, v := range i.([]float64) {
|
||||
array = append(array, v)
|
||||
}
|
||||
// 不是常见类型,则使用反射
|
||||
default:
|
||||
// Finally we use reflection.
|
||||
rv := reflect.ValueOf(i)
|
||||
kind := rv.Kind()
|
||||
// 如果是指针,那么需要转换到指针对应的数据项,以便识别真实的类型
|
||||
// If it's pointer, find the real type.
|
||||
if kind == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
kind = rv.Kind()
|
||||
@ -314,7 +314,7 @@ func Interfaces(i interface{}) []interface{} {
|
||||
case reflect.Struct:
|
||||
rt := rv.Type()
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
// 只获取公开属性
|
||||
// Only public attributes.
|
||||
if !gstr.IsLetterUpper(rt.Field(i).Name[0]) {
|
||||
continue
|
||||
}
|
||||
@ -328,7 +328,7 @@ func Interfaces(i interface{}) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// 将类型转换为[]map[string]interface{}类型.
|
||||
// Maps converts <i> to []map[string]interface{}.
|
||||
func Maps(i interface{}) []map[string]interface{} {
|
||||
if i == nil {
|
||||
return nil
|
||||
|
@ -15,12 +15,18 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 将params键值对参数映射到对应的struct对象属性上,
|
||||
// 第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。
|
||||
// 需要注意:
|
||||
// 1、第二个参数应当为struct对象指针;
|
||||
// 2、struct对象的**公开属性(首字母大写)**才能被映射赋值;
|
||||
// 3、map中的键名可以为小写,映射转换时会自动将键名首字母转为大写做匹配映射,如果无法匹配则忽略;
|
||||
// Struct maps the params key-value pairs to the corresponding struct object properties.
|
||||
// The third parameter mapping is unnecessary, indicating the mapping between the custom name
|
||||
// and the attribute name.
|
||||
//
|
||||
// Note:
|
||||
// 1. The <params> can be any type of may/struct, usually a map;
|
||||
// 2. The second parameter <objPointer> should be a pointer to the struct object;
|
||||
// 3. Only the public attributes of struct object can be mapped;
|
||||
// 4. If <params> is a map, the key of the map <params> can be lowercase.
|
||||
// It will automatically convert the first letter of the key to uppercase
|
||||
// in mapping procedure to do the matching.
|
||||
// If it does not match, ignore the key;
|
||||
func Struct(params interface{}, objPointer interface{}, attrMapping...map[string]string) error {
|
||||
if params == nil {
|
||||
return errors.New("params cannot be nil")
|
||||
|
@ -12,12 +12,14 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 将变量i转换为time.Time类型。
|
||||
// Time converts <i> to time.Time.
|
||||
func Time(i interface{}, format...string) time.Time {
|
||||
return GTime(i, format...).Time
|
||||
}
|
||||
|
||||
// 将变量i转换为time.Duration类型,支持字符串格式。
|
||||
// TimeDuration converts <i> to time.Duration.
|
||||
// If <i> is string, then it uses time.ParseDuration to convert it.
|
||||
// If <i> is numeric, then it converts <i> as nanoseconds.
|
||||
func TimeDuration(i interface{}) time.Duration {
|
||||
s := String(i)
|
||||
if !gstr.IsNumeric(s) {
|
||||
@ -27,13 +29,16 @@ func TimeDuration(i interface{}) time.Duration {
|
||||
return time.Duration(Int64(i))
|
||||
}
|
||||
|
||||
// 将变量i转换为time.Time类型, 自动识别i为时间戳或者标准化的时间字符串。
|
||||
// GTime converts <i> to *gtime.Time.
|
||||
// The parameter <format> can be used to specify the format of <i>.
|
||||
// If no <format> given, it converts <i> using gtime.NewFromTimeStamp if <i> is numeric,
|
||||
// or using gtime.StrToTime if <i> is string.
|
||||
func GTime(i interface{}, format...string) *gtime.Time {
|
||||
s := String(i)
|
||||
if len(s) == 0 {
|
||||
return gtime.New()
|
||||
}
|
||||
// 优先使用用户输入日期格式进行转换
|
||||
// Priority conversion using given format.
|
||||
if len(format) > 0 {
|
||||
t, _ := gtime.StrToTimeFormat(s, format[0])
|
||||
return t
|
||||
|
@ -4,9 +4,7 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package grand provides high performance API for random functionality.
|
||||
//
|
||||
// 随机数管理.
|
||||
// Package grand provides high performance random string generation functionality.
|
||||
package grand
|
||||
|
||||
var (
|
||||
@ -14,86 +12,96 @@ var (
|
||||
digits = []rune("0123456789")
|
||||
)
|
||||
|
||||
// 随机计算是否满足给定的概率(分子/分母)
|
||||
// Meet randomly calculate whether the given probability <num>/<total> is met.
|
||||
func Meet(num, total int) bool {
|
||||
return Intn(total) < num
|
||||
}
|
||||
|
||||
// 随机计算是否满足给定的概率(float32)
|
||||
// MeetProb randomly calculate whether the given probability is met.
|
||||
func MeetProb(prob float32) bool {
|
||||
return Intn(1e7) < int(prob*1e7)
|
||||
}
|
||||
|
||||
// Rand 别名, 返回: [min, max]
|
||||
// N returns a random int between min and max - [min, max].
|
||||
func N (min, max int) int {
|
||||
return Rand(min, max)
|
||||
if min >= max {
|
||||
return min
|
||||
}
|
||||
if min >= 0 {
|
||||
// Because Intn dose not support negative number,
|
||||
// so we should first shift the value to left,
|
||||
// then call Intn to produce the random number,
|
||||
// and finally shift the result to right.
|
||||
return Intn(max - (min - 0) + 1) + (min - 0)
|
||||
}
|
||||
if min < 0 {
|
||||
// Because Intn dose not support negative number,
|
||||
// so we should first shift the value to right,
|
||||
// then call Intn to produce the random number,
|
||||
// and finally shift the result to left.
|
||||
return Intn(max + (0 - min) + 1) - (0 - min)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 获得一个 min, max 之间的随机数: [min, max]
|
||||
// Deprecated.
|
||||
// Alias of N.
|
||||
func Rand (min, max int) int {
|
||||
if min >= max {
|
||||
return min
|
||||
}
|
||||
if min >= 0 {
|
||||
// 数值往左平移,再使用底层随机方法获得随机数,随后将结果数值往右平移
|
||||
return Intn(max - (min - 0) + 1) + (min - 0)
|
||||
}
|
||||
if min < 0 {
|
||||
// 数值往右平移,再使用底层随机方法获得随机数,随后将结果数值往左平移
|
||||
return Intn(max + (0 - min) + 1) - (0 - min)
|
||||
}
|
||||
return 0
|
||||
return N(min, max)
|
||||
}
|
||||
|
||||
// RandStr 别名
|
||||
// Str returns a random string which contains digits and letters, and its length is <n>.
|
||||
func Str(n int) string {
|
||||
return RandStr(n)
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
if Intn(2) == 1 {
|
||||
b[i] = digits[Intn(10)]
|
||||
} else {
|
||||
b[i] = letters[Intn(52)]
|
||||
}
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// 获得指定长度的随机字符串(可能包含数字和字母)
|
||||
// Deprecated.
|
||||
// Alias of Str.
|
||||
func RandStr(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
if Intn(2) == 1 {
|
||||
b[i] = digits[Intn(10)]
|
||||
} else {
|
||||
b[i] = letters[Intn(52)]
|
||||
}
|
||||
}
|
||||
return string(b)
|
||||
return Str(n)
|
||||
}
|
||||
|
||||
// RandDigits 别名
|
||||
// Digits returns a random string which contains only digits, and its length is <n>.
|
||||
func Digits(n int) string {
|
||||
return RandDigits(n)
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = digits[Intn(10)]
|
||||
}
|
||||
return string(b)
|
||||
|
||||
}
|
||||
|
||||
// 获得指定长度的随机数字字符串
|
||||
// Deprecated.
|
||||
// Alias of Digits.
|
||||
func RandDigits(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = digits[Intn(10)]
|
||||
}
|
||||
return string(b)
|
||||
return Digits(n)
|
||||
}
|
||||
|
||||
// RandLetters 别名
|
||||
// Letters returns a random string which contains only letters, and its length is <n>.
|
||||
func Letters(n int) string {
|
||||
return RandLetters(n)
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[Intn(52)]
|
||||
}
|
||||
return string(b)
|
||||
|
||||
}
|
||||
|
||||
// 获得指定长度的随机字母字符串
|
||||
// Deprecated.
|
||||
// Alias of Letters.
|
||||
func RandLetters(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[Intn(52)]
|
||||
}
|
||||
return string(b)
|
||||
return Letters(n)
|
||||
}
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
//
|
||||
// 返回[0, n)的随机数组成的slice。
|
||||
func Perm(n int) []int {
|
||||
m := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
|
@ -13,14 +13,18 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
gBUFFER_SIZE = 10000 // 缓冲区uint32数量大小
|
||||
// Buffer size for uint32 random number.
|
||||
gBUFFER_SIZE = 10000
|
||||
)
|
||||
|
||||
var (
|
||||
// Buffer chan.
|
||||
bufferChan = make(chan uint32, gBUFFER_SIZE)
|
||||
)
|
||||
|
||||
// 使用缓冲区实现快速的随机数生成
|
||||
// It uses a asychronous goroutine to produce the random number,
|
||||
// and a buffer chan to store the random number. So it has high performance
|
||||
// to generate random number.
|
||||
func init() {
|
||||
step := 0
|
||||
buffer := make([]byte, 1024)
|
||||
@ -54,7 +58,11 @@ func init() {
|
||||
}()
|
||||
}
|
||||
|
||||
// 自定义的 rand.Intn ,绝对随机, 返回: [0, max)
|
||||
// Intn returns a int number which is between 0 and max - [0, max).
|
||||
//
|
||||
// Note:
|
||||
// 1. The result is greater than or equal to 0, but less than <max>;
|
||||
// 2. The result number is 32bit and less than math.MaxUint32.
|
||||
func Intn (max int) int {
|
||||
n := int(<- bufferChan)%max
|
||||
if (max > 0 && n < 0) || (max < 0 && n > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user