comments update

This commit is contained in:
John 2019-05-08 21:03:04 +08:00
parent 7cc0c7a1cc
commit 8138215597
11 changed files with 191 additions and 173 deletions

View File

@ -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()

View File

@ -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)
}

View File

@ -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.

View File

@ -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)
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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++ {

View File

@ -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) {