diff --git a/g/database/gredis/gredis.go b/g/database/gredis/gredis.go index a8b0e8778..aefc92e77 100644 --- a/g/database/gredis/gredis.go +++ b/g/database/gredis/gredis.go @@ -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 param is unnecessary, if 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() diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index 01ea1c416..5350a2fb3 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -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) } diff --git a/g/os/gcron/gcron_cron.go b/g/os/gcron/gcron_cron.go index 959a5cc7b..2a9bf402a 100644 --- a/g/os/gcron/gcron_cron.go +++ b/g/os/gcron/gcron_cron.go @@ -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. diff --git a/g/test/gtest/gtest.go b/g/test/gtest/gtest.go index 80f58bd05..ba66e3830 100644 --- a/g/test/gtest/gtest.go +++ b/g/test/gtest/gtest.go @@ -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) } diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index f3a95c205..d3076ece8 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -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 to the type , the type is specified by string. +// The unnecessary parameter 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 to []byte. func Bytes(i interface{}) []byte { if i == nil { return nil @@ -87,7 +86,7 @@ func Bytes(i interface{}) []byte { } } -// 基础的字符串类型转换 +// String converts 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 to bool. +// It returns false if 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 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 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 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 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 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 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 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 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 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 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 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 to float64. func Float64 (i interface{}) float64 { if i == nil { return 0 diff --git a/g/util/gconv/gconv_map.go b/g/util/gconv/gconv_map.go index 7859fe330..038651096 100644 --- a/g/util/gconv/gconv_map.go +++ b/g/util/gconv/gconv_map.go @@ -13,9 +13,11 @@ import ( "strings" ) -// 任意类型转换为 map[string]interface{} 类型, -// 如果给定的输入参数i不是map类型,那么转换会失败,返回nil. -// 当i为struct对象时,第二个参数noTagCheck表示不检测json标签,否则将会使用json tag作为map的键名。 +// Map converts any variable to map[string]interface{}. +// If the parameter is not a map type, then the conversion will fail and returns nil. +// If 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 diff --git a/g/util/gconv/gconv_slice.go b/g/util/gconv/gconv_slice.go index e8eb98e70..7cae7c003 100644 --- a/g/util/gconv/gconv_slice.go +++ b/g/util/gconv/gconv_slice.go @@ -11,7 +11,7 @@ import ( "reflect" ) -// 任意类型转换为[]int类型 +// Ints converts to []int. func Ints(i interface{}) []int { if i == nil { return nil @@ -84,7 +84,7 @@ func Ints(i interface{}) []int { } } -// 任意类型转换为[]string类型 +// Strings converts to []string. func Strings(i interface{}) []string { if i == nil { return nil @@ -157,7 +157,7 @@ func Strings(i interface{}) []string { } } -// 将类型转换为[]float64类型 +// Strings converts to []float64. func Floats(i interface{}) []float64 { if i == nil { return nil @@ -230,7 +230,7 @@ func Floats(i interface{}) []float64 { } } -// 任意类型转换为[]interface{}类型 +// Interfaces converts 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 to []map[string]interface{}. func Maps(i interface{}) []map[string]interface{} { if i == nil { return nil diff --git a/g/util/gconv/gconv_struct.go b/g/util/gconv/gconv_struct.go index 87e220006..879bf7826 100644 --- a/g/util/gconv/gconv_struct.go +++ b/g/util/gconv/gconv_struct.go @@ -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 can be any type of may/struct, usually a map; +// 2. The second parameter should be a pointer to the struct object; +// 3. Only the public attributes of struct object can be mapped; +// 4. If is a map, the key of the map 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") diff --git a/g/util/gconv/gconv_time.go b/g/util/gconv/gconv_time.go index a509d1b48..b17e3c748 100644 --- a/g/util/gconv/gconv_time.go +++ b/g/util/gconv/gconv_time.go @@ -12,12 +12,14 @@ import ( "time" ) -// 将变量i转换为time.Time类型。 +// Time converts to time.Time. func Time(i interface{}, format...string) time.Time { return GTime(i, format...).Time } -// 将变量i转换为time.Duration类型,支持字符串格式。 +// TimeDuration converts to time.Duration. +// If is string, then it uses time.ParseDuration to convert it. +// If is numeric, then it converts 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 to *gtime.Time. +// The parameter can be used to specify the format of . +// If no given, it converts using gtime.NewFromTimeStamp if is numeric, +// or using gtime.StrToTime if 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 diff --git a/g/util/grand/grand.go b/g/util/grand/grand.go index 77278110f..22ecafb0c 100644 --- a/g/util/grand/grand.go +++ b/g/util/grand/grand.go @@ -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 / 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 . 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 . 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 . 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++ { diff --git a/g/util/grand/grand_intn.go b/g/util/grand/grand_intn.go index 14dcc032e..cb4cf3d1e 100644 --- a/g/util/grand/grand_intn.go +++ b/g/util/grand/grand_intn.go @@ -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 ; +// 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) {