github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/function.go (about)

     1  package kgo
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/md5"
     6  	"crypto/sha1"
     7  	"crypto/sha256"
     8  	"crypto/sha512"
     9  	"encoding/base64"
    10  	"encoding/binary"
    11  	"encoding/hex"
    12  	"encoding/json"
    13  	"errors"
    14  	"fmt"
    15  	"hash"
    16  	"reflect"
    17  	"strconv"
    18  	"strings"
    19  	"unicode"
    20  	"unicode/utf8"
    21  	"unsafe"
    22  )
    23  
    24  // dumpPrint 打印调试变量,变量可多个.
    25  func dumpPrint(vs ...interface{}) {
    26  	for _, v := range vs {
    27  		fmt.Printf("%+v\n", v)
    28  		//fmt.Printf("%#v\n", v)
    29  	}
    30  }
    31  
    32  // lenArrayOrSlice 获取数组/切片的长度.
    33  // chkType为检查类型,枚举值有(1仅数组,2仅切片,3数组或切片);结果为-1表示变量不是数组或切片,>=0表示合法长度.
    34  func lenArrayOrSlice(val interface{}, chkType uint8) int {
    35  	if chkType != 1 && chkType != 2 && chkType != 3 {
    36  		chkType = 3
    37  	}
    38  
    39  	var res = -1
    40  	refVal := reflect.ValueOf(val)
    41  	switch refVal.Kind() {
    42  	case reflect.Array:
    43  		if chkType == 1 || chkType == 3 {
    44  			res = refVal.Len()
    45  		}
    46  	case reflect.Slice:
    47  		if chkType == 2 || chkType == 3 {
    48  			res = refVal.Len()
    49  		}
    50  	}
    51  
    52  	return res
    53  }
    54  
    55  // isBool 是否布尔值.
    56  func isBool(val interface{}) bool {
    57  	return val == true || val == false
    58  }
    59  
    60  // isMap 检查变量是否字典.
    61  func isMap(val interface{}) bool {
    62  	return reflect.ValueOf(val).Kind() == reflect.Map
    63  }
    64  
    65  // isStruct 检查变量是否结构体.
    66  func isStruct(val interface{}) bool {
    67  	r := reflectPtr(reflect.ValueOf(val))
    68  	return r.Kind() == reflect.Struct
    69  }
    70  
    71  // isInterface 变量是否接口.
    72  func isInterface(val interface{}) bool {
    73  	r := reflectPtr(reflect.ValueOf(val))
    74  	return r.Kind() == reflect.Invalid
    75  }
    76  
    77  // isString 变量是否字符串.
    78  func isString(val interface{}) bool {
    79  	return GetVariateType(val) == "string"
    80  }
    81  
    82  // isByte 变量是否字节切片.
    83  func isByte(val interface{}) bool {
    84  	return GetVariateType(val) == "[]uint8"
    85  }
    86  
    87  // isBinary 字符串是否二进制.
    88  func isBinary(s string) bool {
    89  	for _, b := range s {
    90  		if 0 == b {
    91  			return true
    92  		}
    93  	}
    94  	return false
    95  }
    96  
    97  // isHex 是否十六进制字符串.
    98  func isHex(str string) (res bool) {
    99  	if len(str) > 0 {
   100  		_, err := hex2Byte(str)
   101  		res = (err == nil)
   102  	}
   103  
   104  	return
   105  }
   106  
   107  // isInt 变量是否整型数值.
   108  func isInt(val interface{}) bool {
   109  	switch val.(type) {
   110  	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
   111  		return true
   112  	case string:
   113  		str := val.(string)
   114  		if str == "" {
   115  			return false
   116  		}
   117  		_, err := strconv.Atoi(str)
   118  		return err == nil
   119  	}
   120  
   121  	return false
   122  }
   123  
   124  // isFloat 变量是否浮点数值.
   125  func isFloat(val interface{}) bool {
   126  	switch val.(type) {
   127  	case float32, float64:
   128  		return true
   129  	case string:
   130  		str := val.(string)
   131  		if str == "" {
   132  			return false
   133  		}
   134  
   135  		if ok := RegFloat.MatchString(str); ok {
   136  			return true
   137  		}
   138  	}
   139  
   140  	return false
   141  }
   142  
   143  // isNumeric 变量是否数值(不包含复数).
   144  func isNumeric(val interface{}) bool {
   145  	switch val.(type) {
   146  	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
   147  		return true
   148  	case float32, float64:
   149  		return true
   150  	case string:
   151  		str := val.(string)
   152  		if str == "" {
   153  			return false
   154  		}
   155  		_, err := strconv.ParseFloat(str, 64)
   156  		return err == nil
   157  	}
   158  
   159  	return false
   160  }
   161  
   162  // isNil 检查变量是否nil.
   163  func isNil(val interface{}) bool {
   164  	if val == nil {
   165  		return true
   166  	}
   167  
   168  	rv := reflect.ValueOf(val)
   169  	switch rv.Kind() {
   170  	case reflect.Invalid:
   171  		return true
   172  	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface:
   173  		return rv.IsNil()
   174  	}
   175  	return false
   176  }
   177  
   178  // isEmpty 检查变量是否为空.
   179  func isEmpty(val interface{}) bool {
   180  	if val == nil {
   181  		return true
   182  	}
   183  	v := reflect.ValueOf(val)
   184  	switch v.Kind() {
   185  	case reflect.Invalid:
   186  		return true
   187  	case reflect.String, reflect.Array:
   188  		return v.Len() == 0
   189  	case reflect.Map, reflect.Slice:
   190  		return v.Len() == 0 || v.IsNil()
   191  	case reflect.Bool:
   192  		return !v.Bool()
   193  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   194  		return v.Int() == 0
   195  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   196  		return v.Uint() == 0
   197  	case reflect.Float32, reflect.Float64:
   198  		return v.Float() == 0
   199  	case reflect.Interface, reflect.Ptr:
   200  		return v.IsNil()
   201  	}
   202  
   203  	return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())
   204  }
   205  
   206  // isLittleEndian 系统字节序类型是否小端存储.
   207  func isLittleEndian() bool {
   208  	var i int32 = 0x01020304
   209  
   210  	// 将int32类型的指针转换为byte类型的指针
   211  	u := unsafe.Pointer(&i)
   212  	pb := (*byte)(u)
   213  
   214  	// 取得pb位置对应的值
   215  	b := *pb
   216  
   217  	// 由于b是byte类型的,最多保存8位,那么只能取得开始的8位
   218  	// 小端: 04 (03 02 01)
   219  	// 大端: 01 (02 03 04)
   220  	return (b == 0x04)
   221  }
   222  
   223  // getEndian 获取系统字节序类型,小端返回binary.LittleEndian,大端返回binary.BigEndian .
   224  func getEndian() binary.ByteOrder {
   225  	var nativeEndian binary.ByteOrder = binary.BigEndian
   226  	buf := [2]byte{}
   227  	*(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD)
   228  
   229  	switch buf {
   230  	case [2]byte{0xCD, 0xAB}:
   231  		nativeEndian = binary.LittleEndian
   232  		//case [2]byte{0xAB, 0xCD}:
   233  		//	nativeEndian = binary.BigEndian
   234  	}
   235  
   236  	return nativeEndian
   237  }
   238  
   239  // numeric2Float 将数值转换为float64.
   240  func numeric2Float(val interface{}) (res float64, err error) {
   241  	switch val.(type) {
   242  	case int:
   243  		res = float64(val.(int))
   244  	case int8:
   245  		res = float64(val.(int8))
   246  	case int16:
   247  		res = float64(val.(int16))
   248  	case int32:
   249  		res = float64(val.(int32))
   250  	case int64:
   251  		res = float64(val.(int64))
   252  	case uint:
   253  		res = float64(val.(uint))
   254  	case uint8:
   255  		res = float64(val.(uint8))
   256  	case uint16:
   257  		res = float64(val.(uint16))
   258  	case uint32:
   259  		res = float64(val.(uint32))
   260  	case uint64:
   261  		res = float64(val.(uint64))
   262  	case float32:
   263  		res = float64(val.(float32))
   264  	case float64:
   265  		res = val.(float64)
   266  	case string:
   267  		str := val.(string)
   268  		res, err = strconv.ParseFloat(str, 64)
   269  	}
   270  	return
   271  }
   272  
   273  // md5Byte 计算字节切片的 MD5 散列值.
   274  func md5Byte(str []byte, length uint8) []byte {
   275  	var res []byte
   276  	h := md5.New()
   277  	_, _ = h.Write(str)
   278  
   279  	hBytes := h.Sum(nil)
   280  	dst := make([]byte, hex.EncodedLen(len(hBytes)))
   281  	hex.Encode(dst, hBytes)
   282  	if length > 0 && length < 32 {
   283  		res = dst[:length]
   284  	} else {
   285  		res = dst
   286  	}
   287  
   288  	return res
   289  }
   290  
   291  // shaXByte 计算字节切片的 shaX 散列值,x为1/256/512.
   292  func shaXByte(str []byte, x uint16) []byte {
   293  	var h hash.Hash
   294  	switch x {
   295  	case 1:
   296  		h = sha1.New()
   297  		break
   298  	case 256:
   299  		h = sha256.New()
   300  		break
   301  	case 512:
   302  		h = sha512.New()
   303  		break
   304  	default:
   305  		panic(fmt.Sprintf("[shaXByte]`x must be in [1, 256, 512]; but: %d", x))
   306  	}
   307  
   308  	h.Write(str)
   309  
   310  	hBytes := h.Sum(nil)
   311  	res := make([]byte, hex.EncodedLen(len(hBytes)))
   312  	hex.Encode(res, hBytes)
   313  	return res
   314  }
   315  
   316  // arrayValues 返回arr(数组/切片/字典/结构体)中所有的值.
   317  // filterZero 是否过滤零值元素(nil,false,0,'',[]),true时排除零值元素,false时保留零值元素.
   318  func arrayValues(arr interface{}, filterZero bool) []interface{} {
   319  	var res []interface{}
   320  	var fieldVal reflect.Value
   321  	val := reflect.ValueOf(arr)
   322  	switch val.Kind() {
   323  	case reflect.Array, reflect.Slice:
   324  		for i := 0; i < val.Len(); i++ {
   325  			fieldVal = val.Index(i)
   326  			if !filterZero || (filterZero && !fieldVal.IsZero()) {
   327  				res = append(res, fieldVal.Interface())
   328  			}
   329  		}
   330  	case reflect.Map:
   331  		for _, k := range val.MapKeys() {
   332  			fieldVal = val.MapIndex(k)
   333  			if !filterZero || (filterZero && !fieldVal.IsZero()) {
   334  				res = append(res, fieldVal.Interface())
   335  			}
   336  		}
   337  	case reflect.Struct:
   338  		for i := 0; i < val.NumField(); i++ {
   339  			fieldVal = val.Field(i)
   340  			if fieldVal.CanInterface() {
   341  				if !filterZero || (filterZero && !fieldVal.IsZero()) {
   342  					res = append(res, fieldVal.Interface())
   343  				}
   344  			}
   345  		}
   346  	default:
   347  		panic("[arrayValues]`arr type must be array|slice|map|struct; but : " + val.Kind().String())
   348  	}
   349  
   350  	return res
   351  }
   352  
   353  // reflectPtr 获取反射的指向.
   354  func reflectPtr(r reflect.Value) reflect.Value {
   355  	// 如果是指针,则获取其所指向的元素
   356  	if r.Kind() == reflect.Ptr {
   357  		r = r.Elem()
   358  	}
   359  	return r
   360  }
   361  
   362  // reflect2Itf 将反射值转为接口(原值)
   363  func reflect2Itf(r reflect.Value) (res interface{}) {
   364  	switch r.Kind() {
   365  	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
   366  		res = r.Int()
   367  	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
   368  		res = r.Uint()
   369  	case reflect.Float32, reflect.Float64:
   370  		res = r.Float()
   371  	case reflect.String:
   372  		res = r.String()
   373  	case reflect.Bool:
   374  		res = r.Bool()
   375  	default:
   376  		if r.CanInterface() {
   377  			res = r.Interface()
   378  		} else {
   379  			res = r
   380  		}
   381  	}
   382  
   383  	return
   384  }
   385  
   386  // structVal 获取结构体的反射值.
   387  func structVal(obj interface{}) (reflect.Value, error) {
   388  	v := reflect.ValueOf(obj)
   389  
   390  	for v.Kind() == reflect.Ptr {
   391  		v = v.Elem()
   392  	}
   393  
   394  	if v.Kind() != reflect.Struct {
   395  		return v, errors.New("[structVal]`obj type must be struct; but : " + v.Kind().String())
   396  	}
   397  
   398  	return v, nil
   399  }
   400  
   401  // structFields 获取结构体的字段;all是否包含所有字段(包括未导出的).
   402  func structFields(obj interface{}, all bool) ([]reflect.StructField, error) {
   403  	v, e := structVal(obj)
   404  	if e != nil {
   405  		return nil, e
   406  	}
   407  
   408  	var fs []reflect.StructField
   409  	var t = v.Type()
   410  	for i := 0; i < t.NumField(); i++ {
   411  		field := t.Field(i)
   412  		// 不能访问未导出的字段
   413  		if !all && field.PkgPath != "" {
   414  			continue
   415  		}
   416  
   417  		fs = append(fs, field)
   418  	}
   419  
   420  	return fs, nil
   421  }
   422  
   423  // struct2Map 结构体转为字典;tagName为要导出的标签名,可以为空,为空时将导出所有字段.
   424  func struct2Map(obj interface{}, tagName string) (map[string]interface{}, error) {
   425  	v, e := structVal(obj)
   426  	if e != nil {
   427  		return nil, e
   428  	}
   429  
   430  	t := v.Type()
   431  	var res = make(map[string]interface{})
   432  	for i := 0; i < t.NumField(); i++ {
   433  		field := t.Field(i)
   434  		if tagName != "" {
   435  			if tagValue := field.Tag.Get(tagName); tagValue != "" {
   436  				res[tagValue] = reflect2Itf(v.Field(i))
   437  			}
   438  		} else {
   439  			res[field.Name] = reflect2Itf(v.Field(i))
   440  		}
   441  	}
   442  
   443  	return res, nil
   444  }
   445  
   446  // creditChecksum 计算身份证校验码,其中id为身份证号码.
   447  func creditChecksum(id string) byte {
   448  	//∑(ai×Wi)(mod 11)
   449  	// 加权因子
   450  	factor := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
   451  	// 校验位对应值
   452  	code := []byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
   453  
   454  	leng := len(id)
   455  	sum := 0
   456  	for i, char := range id[:leng-1] {
   457  		num, _ := strconv.Atoi(string(char))
   458  		sum += num * factor[i]
   459  	}
   460  
   461  	return code[sum%11]
   462  }
   463  
   464  // compareConditionMap 比对数组是否匹配条件.condition为条件字典,arr为要比对的数据(字典/结构体).
   465  func compareConditionMap(condition map[string]interface{}, arr interface{}) (res interface{}) {
   466  	val := reflect.ValueOf(arr)
   467  	conNum := len(condition)
   468  	if conNum > 0 {
   469  		chkNum := 0
   470  
   471  		switch val.Kind() {
   472  		case reflect.Map:
   473  			if conNum > 0 {
   474  				for _, k := range val.MapKeys() {
   475  					if condVal, ok := condition[k.String()]; ok && reflect.DeepEqual(val.MapIndex(k).Interface(), condVal) {
   476  						chkNum++
   477  					}
   478  				}
   479  			}
   480  		case reflect.Struct:
   481  			var field reflect.Value
   482  			for k, v := range condition {
   483  				field = val.FieldByName(k)
   484  
   485  				if field.IsValid() && field.CanInterface() && reflect.DeepEqual(field.Interface(), v) {
   486  					chkNum++
   487  				}
   488  			}
   489  		default:
   490  			panic("[compareConditionMap]`arr type must be map|struct; but : " + val.Kind().String())
   491  		}
   492  
   493  		if chkNum == conNum {
   494  			res = arr
   495  		}
   496  	}
   497  
   498  	return
   499  }
   500  
   501  // getTrimMask 获取要修剪的字符串集合,masks为要屏蔽的字符切片.
   502  func getTrimMask(masks []string) string {
   503  	var str string
   504  	if len(masks) == 0 {
   505  		str = blankChars
   506  	} else {
   507  		str = strings.Join(masks, "")
   508  	}
   509  	return str
   510  }
   511  
   512  // methodExists 检查val结构体中是否存在methodName方法.
   513  func methodExists(val interface{}, methodName string) (bool, error) {
   514  	if methodName == "" {
   515  		return false, errors.New("[methodExists]`methodName can not be empty.")
   516  	}
   517  
   518  	r := reflect.ValueOf(val)
   519  	if r.Type().Kind() != reflect.Ptr {
   520  		r = reflect.New(reflect.TypeOf(val))
   521  	}
   522  
   523  	method := r.MethodByName(methodName)
   524  	if !method.IsValid() {
   525  		return false, fmt.Errorf("[methodExists] Method `%s` not exists in interface `%s`", methodName, r.Type())
   526  	}
   527  
   528  	return true, nil
   529  }
   530  
   531  // getMethod 获取val结构体的methodName方法.
   532  // 注意:返回的方法中的第一个参数是接收者.
   533  // 所以,调用返回的方法时,必须将接收者作为第一个参数传递.
   534  func getMethod(val interface{}, methodName string) interface{} {
   535  	if val == nil || methodName == "" {
   536  		return nil
   537  	}
   538  
   539  	r := reflect.ValueOf(val)
   540  	if r.Type().Kind() != reflect.Ptr {
   541  		r = reflect.New(reflect.TypeOf(val))
   542  	}
   543  
   544  	method := r.MethodByName(methodName)
   545  	if !method.IsValid() {
   546  		return nil
   547  	}
   548  
   549  	return method.Interface()
   550  }
   551  
   552  // getFuncNames 获取变量的所有函数名.
   553  func getFuncNames(val interface{}) (res []string) {
   554  	if val == nil {
   555  		return
   556  	}
   557  
   558  	r := reflect.ValueOf(val)
   559  	if r.Type().Kind() != reflect.Ptr {
   560  		r = reflect.New(reflect.TypeOf(val))
   561  	}
   562  
   563  	typ := r.Type()
   564  	for i := 0; i < r.NumMethod(); i++ {
   565  		res = append(res, typ.Method(i).Name)
   566  	}
   567  	return
   568  }
   569  
   570  // camelCaseToLowerCase 驼峰转为小写.
   571  func camelCaseToLowerCase(str string, connector rune) string {
   572  	if len(str) == 0 {
   573  		return ""
   574  	}
   575  
   576  	buf := &bytes.Buffer{}
   577  	var prev, r0, r1 rune
   578  	var size int
   579  
   580  	r0 = connector
   581  
   582  	for len(str) > 0 {
   583  		prev = r0
   584  		r0, size = utf8.DecodeRuneInString(str)
   585  		str = str[size:]
   586  
   587  		switch {
   588  		case r0 == utf8.RuneError:
   589  			continue
   590  
   591  		case unicode.IsUpper(r0):
   592  			if prev != connector && !unicode.IsNumber(prev) {
   593  				buf.WriteRune(connector)
   594  			}
   595  
   596  			buf.WriteRune(unicode.ToLower(r0))
   597  
   598  			if len(str) == 0 {
   599  				break
   600  			}
   601  
   602  			r0, size = utf8.DecodeRuneInString(str)
   603  			str = str[size:]
   604  
   605  			if !unicode.IsUpper(r0) {
   606  				buf.WriteRune(r0)
   607  				break
   608  			}
   609  
   610  			// find next non-upper-case character and insert connector properly.
   611  			// it's designed to convert `HTTPServer` to `http_server`.
   612  			// if there are more than 2 adjacent upper case characters in a word,
   613  			// treat them as an abbreviation plus a normal word.
   614  			for len(str) > 0 {
   615  				r1 = r0
   616  				r0, size = utf8.DecodeRuneInString(str)
   617  				str = str[size:]
   618  
   619  				if r0 == utf8.RuneError {
   620  					buf.WriteRune(unicode.ToLower(r1))
   621  					break
   622  				}
   623  
   624  				if !unicode.IsUpper(r0) {
   625  					if isCaseConnector(r0) {
   626  						r0 = connector
   627  
   628  						buf.WriteRune(unicode.ToLower(r1))
   629  					} else if unicode.IsNumber(r0) {
   630  						// treat a number as an upper case rune
   631  						// so that both `http2xx` and `HTTP2XX` can be converted to `http_2xx`.
   632  						buf.WriteRune(unicode.ToLower(r1))
   633  						buf.WriteRune(connector)
   634  						buf.WriteRune(r0)
   635  					} else {
   636  						buf.WriteRune(connector)
   637  						buf.WriteRune(unicode.ToLower(r1))
   638  						buf.WriteRune(r0)
   639  					}
   640  
   641  					break
   642  				}
   643  
   644  				buf.WriteRune(unicode.ToLower(r1))
   645  			}
   646  
   647  			if len(str) == 0 || r0 == connector {
   648  				buf.WriteRune(unicode.ToLower(r0))
   649  			}
   650  
   651  		case unicode.IsNumber(r0):
   652  			if prev != connector && !unicode.IsNumber(prev) {
   653  				buf.WriteRune(connector)
   654  			}
   655  
   656  			buf.WriteRune(r0)
   657  
   658  		default:
   659  			if isCaseConnector(r0) {
   660  				r0 = connector
   661  			}
   662  
   663  			buf.WriteRune(r0)
   664  		}
   665  	}
   666  
   667  	return buf.String()
   668  }
   669  
   670  // isCaseConnector 是否字符转换连接符.
   671  func isCaseConnector(r rune) bool {
   672  	return r == '-' || r == '_' || unicode.IsSpace(r)
   673  }
   674  
   675  // pkcs7Padding PKCS7填充.
   676  // cipherText为密文;blockSize为分组长度;isZero是否零填充.
   677  func pkcs7Padding(cipherText []byte, blockSize int, isZero bool) []byte {
   678  	clen := len(cipherText)
   679  	if cipherText == nil || clen == 0 || blockSize <= 0 {
   680  		return nil
   681  	}
   682  
   683  	var padtext []byte
   684  	padding := blockSize - clen%blockSize
   685  	if isZero {
   686  		padtext = bytes.Repeat([]byte{0}, padding)
   687  	} else {
   688  		padtext = bytes.Repeat([]byte{byte(padding)}, padding)
   689  	}
   690  
   691  	return append(cipherText, padtext...)
   692  }
   693  
   694  // pkcs7UnPadding PKCS7拆解.
   695  // origData为源数据;blockSize为分组长度.
   696  func pkcs7UnPadding(origData []byte, blockSize int) []byte {
   697  	//origData = zeroUnPadding(origData)
   698  	olen := len(origData)
   699  	if origData == nil || olen == 0 || blockSize <= 0 || olen%blockSize != 0 {
   700  		return nil
   701  	}
   702  
   703  	unpadding := int(origData[olen-1])
   704  	if unpadding > olen {
   705  		return nil
   706  	}
   707  
   708  	return origData[:(olen - unpadding)]
   709  }
   710  
   711  // zeroPadding PKCS7使用0填充.
   712  func zeroPadding(cipherText []byte, blockSize int) []byte {
   713  	return pkcs7Padding(cipherText, blockSize, true)
   714  }
   715  
   716  // zeroUnPadding PKCS7-0拆解.
   717  func zeroUnPadding(origData []byte) []byte {
   718  	return bytes.TrimRightFunc(origData, func(r rune) bool {
   719  		return r == rune(0)
   720  	})
   721  }
   722  
   723  // GetFieldValue 获取(字典/结构体的)字段值;fieldName为字段名,大小写敏感.
   724  func GetFieldValue(arr interface{}, fieldName string) (res interface{}, err error) {
   725  	val := reflect.ValueOf(arr)
   726  	switch val.Kind() {
   727  	case reflect.Map:
   728  		for _, subKey := range val.MapKeys() {
   729  			if fmt.Sprintf("%s", subKey) == fieldName {
   730  				res = val.MapIndex(subKey).Interface()
   731  				break
   732  			}
   733  		}
   734  	case reflect.Struct:
   735  		field := val.FieldByName(fieldName)
   736  		if !field.IsValid() || !field.CanInterface() {
   737  			break
   738  		}
   739  		res = field.Interface()
   740  	default:
   741  		err = errors.New("[GetFieldValue]`arr type must be map|struct; but : " + val.Kind().String())
   742  	}
   743  
   744  	return
   745  }
   746  
   747  // str2Int 将字符串转换为int.其中"true", "TRUE", "True"为1;若为浮点字符串,则取整数部分.
   748  func str2Int(val string) (res int) {
   749  	if val == "true" || val == "TRUE" || val == "True" {
   750  		res = 1
   751  		return
   752  	} else if ok := RegFloat.MatchString(val); ok {
   753  		fl, _ := strconv.ParseFloat(val, 1)
   754  		res = int(fl)
   755  		return
   756  	}
   757  
   758  	res, _ = strconv.Atoi(val)
   759  	return
   760  }
   761  
   762  // str2Int 将字符串转换为uint.其中"true", "TRUE", "True"为1;若为浮点字符串,则取整数部分;若为负值则为0.
   763  func str2Uint(val string) (res uint) {
   764  	if val == "true" || val == "TRUE" || val == "True" {
   765  		res = 1
   766  		return
   767  	} else if ok := RegFloat.MatchString(val); ok {
   768  		fl, _ := strconv.ParseFloat(val, 1)
   769  		if fl > 0 {
   770  			res = uint(fl)
   771  		}
   772  
   773  		return
   774  	}
   775  
   776  	n, e := strconv.Atoi(val)
   777  	if e == nil && n > 0 {
   778  		res = uint(n)
   779  	}
   780  
   781  	return
   782  }
   783  
   784  // str2Float32 将字符串转换为float32;其中"true", "TRUE", "True"为1.0 .
   785  func str2Float32(val string) (res float32) {
   786  	if val == "true" || val == "TRUE" || val == "True" {
   787  		res = 1.0
   788  	} else {
   789  		r, _ := strconv.ParseFloat(val, 32)
   790  		res = float32(r)
   791  	}
   792  
   793  	return
   794  }
   795  
   796  // str2Float64 将字符串转换为float64;其中"true", "TRUE", "True"为1.0 .
   797  func str2Float64(val string) (res float64) {
   798  	if val == "true" || val == "TRUE" || val == "True" {
   799  		res = 1.0
   800  	} else {
   801  		res, _ = strconv.ParseFloat(val, 64)
   802  	}
   803  
   804  	return
   805  }
   806  
   807  // str2Bool 将字符串转换为布尔值.
   808  // 1, t, T, TRUE, true, True 等字符串为真;
   809  // 0, f, F, FALSE, false, False 等字符串为假.
   810  func str2Bool(val string) (res bool) {
   811  	if val != "" {
   812  		res, _ = strconv.ParseBool(val)
   813  	}
   814  
   815  	return
   816  }
   817  
   818  // bool2Int 将布尔值转换为整型.
   819  func bool2Int(val bool) int {
   820  	if val {
   821  		return 1
   822  	}
   823  	return 0
   824  }
   825  
   826  // str2Bytes 将字符串转换为字节切片.
   827  func str2Bytes(val string) []byte {
   828  	return []byte(val)
   829  }
   830  
   831  // bytes2Str 将字节切片转换为字符串.
   832  func bytes2Str(val []byte) string {
   833  	return string(val)
   834  }
   835  
   836  // str2BytesUnsafe (非安全的)将字符串转换为字节切片.
   837  // 该方法零拷贝,但不安全.它直接转换底层指针,两者指向的相同的内存,改一个另外一个也会变.
   838  // 仅当临时需将长字符串转换且不长时间保存时可以使用.
   839  // 转换之后若没做其他操作直接改变里面的字符,则程序会崩溃.
   840  // 如 b:=str2BytesUnsafe("xxx"); b[1]='d'; 程序将panic.
   841  func str2BytesUnsafe(val string) []byte {
   842  	psHeader := &reflect.SliceHeader{}
   843  	strHeader := (*reflect.StringHeader)(unsafe.Pointer(&val))
   844  	psHeader.Data = strHeader.Data
   845  	psHeader.Len = strHeader.Len
   846  	psHeader.Cap = strHeader.Len
   847  	return *(*[]byte)(unsafe.Pointer(psHeader))
   848  }
   849  
   850  // bytes2StrUnsafe (非安全的)将字节切片转换为字符串.
   851  // 零拷贝,不安全.效率是string([]byte{})的百倍以上,且转换量越大效率优势越明显.
   852  func bytes2StrUnsafe(val []byte) string {
   853  	return *(*string)(unsafe.Pointer(&val))
   854  }
   855  
   856  // runes2Bytes 将[]rune转为[]byte.
   857  func runes2Bytes(rs []rune) []byte {
   858  	size := 0
   859  	for _, r := range rs {
   860  		size += utf8.RuneLen(r)
   861  	}
   862  
   863  	bs := make([]byte, size)
   864  
   865  	count := 0
   866  	for _, r := range rs {
   867  		count += utf8.EncodeRune(bs[count:], r)
   868  	}
   869  
   870  	return bs
   871  }
   872  
   873  // toStr 强制将变量转换为字符串.
   874  func toStr(val interface{}) string {
   875  	//先处理其他类型
   876  	v := reflect.ValueOf(val)
   877  	switch v.Kind() {
   878  	case reflect.Invalid:
   879  		return ""
   880  	case reflect.Bool:
   881  		return strconv.FormatBool(v.Bool())
   882  	case reflect.String:
   883  		return v.String()
   884  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   885  		return strconv.FormatInt(v.Int(), 10)
   886  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   887  		return strconv.FormatUint(v.Uint(), 10)
   888  	case reflect.Float32:
   889  		return strconv.FormatFloat(v.Float(), 'f', -1, 32)
   890  	case reflect.Float64:
   891  		return strconv.FormatFloat(v.Float(), 'f', -1, 64)
   892  	case reflect.Ptr, reflect.Struct, reflect.Map: //指针、结构体和字典
   893  		b, err := json.Marshal(v.Interface())
   894  		if err != nil {
   895  			return ""
   896  		}
   897  		return string(b)
   898  	}
   899  
   900  	//再处理字节切片
   901  	switch val.(type) {
   902  	case []uint8:
   903  		return string(val.([]uint8))
   904  	}
   905  
   906  	return fmt.Sprintf("%v", val)
   907  }
   908  
   909  // toBool 强制将变量转换为布尔值.
   910  // 数值类型将检查值是否>0;
   911  // 字符串将使用str2Bool;
   912  // 数组、切片、字典、通道类型将检查它们的长度是否>0;
   913  // 指针、结构体类型为true,其他为false.
   914  func toBool(val interface{}) (res bool) {
   915  	switch val.(type) {
   916  	case int:
   917  		res = (val.(int) > 0)
   918  	case int8:
   919  		res = (val.(int8) > 0)
   920  	case int16:
   921  		res = (val.(int16) > 0)
   922  	case int32:
   923  		res = (val.(int32) > 0)
   924  	case int64:
   925  		res = (val.(int64) > 0)
   926  	case uint:
   927  		res = (val.(uint) > 0)
   928  	case uint8:
   929  		res = (val.(uint8) > 0)
   930  	case uint16:
   931  		res = (val.(uint16) > 0)
   932  	case uint32:
   933  		res = (val.(uint32) > 0)
   934  	case uint64:
   935  		res = (val.(uint64) > 0)
   936  	case float32:
   937  		res = (val.(float32) > 0)
   938  	case float64:
   939  		res = (val.(float64) > 0)
   940  	case string:
   941  		res = str2Bool(val.(string))
   942  	case bool:
   943  		res = val.(bool)
   944  	default:
   945  		v := reflect.ValueOf(val)
   946  		switch v.Kind() {
   947  		case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan:
   948  			res = v.Len() > 0
   949  		case reflect.Ptr, reflect.Struct:
   950  			res = true
   951  		}
   952  	}
   953  
   954  	return
   955  }
   956  
   957  // toInt 强制将变量转换为整型.
   958  // 数值类型将转为整型;
   959  // 字符串将使用str2Int;
   960  // 布尔型的true为1,false为0;
   961  // 数组、切片、字典、通道类型将取它们的长度;
   962  // 指针、结构体类型为1,其他为0.
   963  func toInt(val interface{}) (res int) {
   964  	switch val.(type) {
   965  	case int:
   966  		res = val.(int)
   967  	case int8:
   968  		res = int(val.(int8))
   969  	case int16:
   970  		res = int(val.(int16))
   971  	case int32:
   972  		res = int(val.(int32))
   973  	case int64:
   974  		res = int(val.(int64))
   975  	case uint:
   976  		res = int(val.(uint))
   977  	case uint8:
   978  		res = int(val.(uint8))
   979  	case uint16:
   980  		res = int(val.(uint16))
   981  	case uint32:
   982  		res = int(val.(uint32))
   983  	case uint64:
   984  		res = int(val.(uint64))
   985  	case float32:
   986  		res = int(val.(float32))
   987  	case float64:
   988  		res = int(val.(float64))
   989  	case string:
   990  		res = str2Int(val.(string))
   991  	case bool:
   992  		res = bool2Int(val.(bool))
   993  	default:
   994  		v := reflect.ValueOf(val)
   995  		switch v.Kind() {
   996  		case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan:
   997  			res = v.Len()
   998  		case reflect.Ptr, reflect.Struct:
   999  			res = 1
  1000  		}
  1001  	}
  1002  
  1003  	return
  1004  }
  1005  
  1006  // toFloat 强制将变量转换为浮点型.
  1007  // 数值类型将转为浮点型;
  1008  // 字符串将使用str2Float64;
  1009  // 布尔型的true为1.0,false为0;
  1010  // 数组、切片、字典、通道类型将取它们的长度;
  1011  // 指针、结构体类型为1.0,其他为0.
  1012  func toFloat(val interface{}) (res float64) {
  1013  	switch val.(type) {
  1014  	case int:
  1015  		res = float64(val.(int))
  1016  	case int8:
  1017  		res = float64(val.(int8))
  1018  	case int16:
  1019  		res = float64(val.(int16))
  1020  	case int32:
  1021  		res = float64(val.(int32))
  1022  	case int64:
  1023  		res = float64(val.(int64))
  1024  	case uint:
  1025  		res = float64(val.(uint))
  1026  	case uint8:
  1027  		res = float64(val.(uint8))
  1028  	case uint16:
  1029  		res = float64(val.(uint16))
  1030  	case uint32:
  1031  		res = float64(val.(uint32))
  1032  	case uint64:
  1033  		res = float64(val.(uint64))
  1034  	case float32:
  1035  		res = float64(val.(float32))
  1036  	case float64:
  1037  		res = val.(float64)
  1038  	case string:
  1039  		res = str2Float64(val.(string))
  1040  	case bool:
  1041  		if val.(bool) {
  1042  			res = 1.0
  1043  		}
  1044  	default:
  1045  		v := reflect.ValueOf(val)
  1046  		switch v.Kind() {
  1047  		case reflect.Array, reflect.Slice, reflect.Map, reflect.Chan:
  1048  			res = float64(v.Len())
  1049  		case reflect.Ptr, reflect.Struct:
  1050  			res = 1.0
  1051  		}
  1052  	}
  1053  
  1054  	return
  1055  }
  1056  
  1057  // dec2Bin 将十进制转换为二进制字符串.
  1058  func dec2Bin(num int64) string {
  1059  	return strconv.FormatInt(num, 2)
  1060  }
  1061  
  1062  // bin2Dec 将二进制字符串转换为十进制.
  1063  func bin2Dec(str string) (int64, error) {
  1064  	i, err := strconv.ParseInt(str, 2, 0)
  1065  	if err != nil {
  1066  		return 0, err
  1067  	}
  1068  	return i, nil
  1069  }
  1070  
  1071  // hex2Bin 将十六进制字符串转换为二进制字符串.
  1072  func hex2Bin(str string) (string, error) {
  1073  	i, err := strconv.ParseInt(str, 16, 0)
  1074  	if err != nil {
  1075  		return "", err
  1076  	}
  1077  	return strconv.FormatInt(i, 2), nil
  1078  }
  1079  
  1080  // bin2Hex 将二进制字符串转换为十六进制字符串.
  1081  func bin2Hex(str string) (string, error) {
  1082  	i, err := strconv.ParseInt(str, 2, 0)
  1083  	if err != nil {
  1084  		return "", err
  1085  	}
  1086  	return strconv.FormatInt(i, 16), nil
  1087  }
  1088  
  1089  // dec2Hex 将十进制转换为十六进制.
  1090  func dec2Hex(num int64) string {
  1091  	return strconv.FormatInt(num, 16)
  1092  }
  1093  
  1094  // hex2Dec 将十六进制转换为十进制.
  1095  func hex2Dec(str string) (int64, error) {
  1096  	start := 0
  1097  	if len(str) > 2 && str[0:2] == "0x" {
  1098  		start = 2
  1099  	}
  1100  
  1101  	// bitSize 表示结果的位宽(包括符号位),0 表示最大位宽
  1102  	return strconv.ParseInt(str[start:], 16, 0)
  1103  }
  1104  
  1105  // hex2Byte 16进制字符串转字节切片.
  1106  func hex2Byte(str string) ([]byte, error) {
  1107  	start := 0
  1108  	if len(str) > 2 && str[0:2] == "0x" {
  1109  		start = 2
  1110  	}
  1111  
  1112  	h, e := hex.DecodeString(str[start:])
  1113  	return h, e
  1114  }
  1115  
  1116  // dec2Oct 将十进制转换为八进制.
  1117  func dec2Oct(num int64) string {
  1118  	return strconv.FormatInt(num, 8)
  1119  }
  1120  
  1121  // oct2Dec 将八进制转换为十进制.
  1122  func oct2Dec(str string) (int64, error) {
  1123  	start := 0
  1124  	if len(str) > 1 && str[0:1] == "0" {
  1125  		start = 1
  1126  	}
  1127  
  1128  	return strconv.ParseInt(str[start:], 8, 0)
  1129  }
  1130  
  1131  // getIntersectStrings 获取两个字符串相同部分的切片.
  1132  // minLen为子串最小长度,为0则不限制.
  1133  func getIntersectStrings(minLen int, str1, str2 string) (res []string) {
  1134  	var lenA, lenB, runesLen int
  1135  	var runes []rune
  1136  	var longStr, itm string
  1137  	var chkMap = make(map[string]bool)
  1138  	var chk, ok bool
  1139  
  1140  	lenA = len(str1)
  1141  	lenB = len(str2)
  1142  
  1143  	if lenA == 0 || lenB == 0 {
  1144  		return
  1145  	}
  1146  
  1147  	if lenA > lenB {
  1148  		longStr = str1
  1149  		runes = []rune(str2)
  1150  	} else {
  1151  		longStr = str2
  1152  		runes = []rune(str1)
  1153  	}
  1154  	runesLen = len(runes)
  1155  
  1156  	for i := 0; i < runesLen; i++ {
  1157  		for j := i + 1; j <= runesLen; j++ {
  1158  			itm = string(runes[i:j])
  1159  			if minLen == 0 || (minLen > 0 && len(itm) >= minLen) {
  1160  				_, ok = chkMap[itm]
  1161  				if !ok {
  1162  					chk = strings.Contains(longStr, itm)
  1163  					chkMap[itm] = true
  1164  					if chk {
  1165  						res = append(res, itm)
  1166  					}
  1167  				}
  1168  			}
  1169  		}
  1170  	}
  1171  
  1172  	return
  1173  }
  1174  
  1175  // longestSameString 获取两个字符串最长相同的子串.
  1176  func longestSameString(str1, str2 string) (res string) {
  1177  	var resLen, itmLen int
  1178  	strs := getIntersectStrings(0, str1, str2)
  1179  	if len(strs) > 0 {
  1180  		res = strs[0]
  1181  		resLen = len(res)
  1182  		for _, v := range strs {
  1183  			itmLen = len(v)
  1184  			if itmLen > resLen {
  1185  				res = v
  1186  				resLen = itmLen
  1187  			}
  1188  		}
  1189  	}
  1190  
  1191  	return
  1192  }
  1193  
  1194  // img2Base64 将图片字节转换为base64字符串.imgType为图片扩展名.
  1195  func img2Base64(content []byte, imgType string) string {
  1196  	return fmt.Sprintf("data:image/%s;base64,%s", imgType, base64.StdEncoding.EncodeToString(content))
  1197  }
  1198  
  1199  // formatPath 格式化路径.
  1200  func formatPath(fpath string) string {
  1201  	//替换特殊字符
  1202  	fpath = strings.NewReplacer(`|`, "", `<`, "", `>`, "", `?`, "", `\`, "/").Replace(fpath)
  1203  	//替换连续斜杠
  1204  	fpath = RegFormatDir.ReplaceAllString(fpath, "/")
  1205  
  1206  	//处理windows路径(带":")
  1207  	slashPos := strings.Index(fpath, "/")
  1208  	colonPos := strings.Index(fpath, ":")
  1209  	if colonPos >= 0 { //路径中存在":"
  1210  		if slashPos == 0 { //路径以"/"开头
  1211  			fpath = strings.ReplaceAll(fpath, ":", "")
  1212  		} else {
  1213  			front := fpath[0 : colonPos+1]
  1214  			back := strings.ReplaceAll(fpath[colonPos:], ":", "")
  1215  			fpath = front + back
  1216  		}
  1217  	}
  1218  
  1219  	return fpath
  1220  }
  1221  
  1222  // formatDir 格式化目录,将"\","//"替换为"/",且以"/"结尾.
  1223  func formatDir(fpath string) string {
  1224  	if fpath == "" {
  1225  		return ""
  1226  	}
  1227  
  1228  	fpath = formatPath(fpath)
  1229  
  1230  	return strings.TrimRight(fpath, "/") + "/"
  1231  }
  1232  
  1233  // buildQueryMap 创建URL Query参数字典.
  1234  // result 为结果字典;keys 为键数组;value为键值.
  1235  func buildQueryMap(result map[string]interface{}, keys []string, value interface{}) error {
  1236  	length := len(keys)
  1237  	// trim ',"
  1238  	key := strings.Trim(keys[0], "',\"")
  1239  	if length == 1 {
  1240  		result[key] = value
  1241  		return nil
  1242  	}
  1243  
  1244  	// The end is slice. like f[], f[a][]
  1245  	if keys[1] == "" && length == 2 {
  1246  		if key == "" {
  1247  			return nil
  1248  		}
  1249  		val, ok := result[key]
  1250  		if !ok {
  1251  			result[key] = []interface{}{value}
  1252  			return nil
  1253  		}
  1254  		children, ok := val.([]interface{})
  1255  		if !ok {
  1256  			return fmt.Errorf("[buildQueryMap] expected type '[]interface{}' for key '%s', but got '%T'", key, val)
  1257  		}
  1258  		result[key] = append(children, value)
  1259  		return nil
  1260  	}
  1261  
  1262  	// The end is slice + map. like f[][a]
  1263  	if keys[1] == "" && length > 2 && keys[2] != "" {
  1264  		val, ok := result[key]
  1265  		if !ok {
  1266  			result[key] = []interface{}{}
  1267  			val = result[key]
  1268  		}
  1269  		children, ok := val.([]interface{})
  1270  		if !ok {
  1271  			return fmt.Errorf("[buildQueryMap] expected type '[]interface{}' for key '%s', but got '%T'", key, val)
  1272  		}
  1273  		if l := len(children); l > 0 {
  1274  			if child, ok := children[l-1].(map[string]interface{}); ok {
  1275  				if _, ok := child[keys[2]]; !ok {
  1276  					_ = buildQueryMap(child, keys[2:], value)
  1277  					return nil
  1278  				}
  1279  			}
  1280  		}
  1281  		child := map[string]interface{}{}
  1282  		_ = buildQueryMap(child, keys[2:], value)
  1283  		result[key] = append(children, child)
  1284  
  1285  		return nil
  1286  	}
  1287  
  1288  	// map. like f[a], f[a][b]
  1289  	val, ok := result[key]
  1290  	if !ok {
  1291  		result[key] = map[string]interface{}{}
  1292  		val = result[key]
  1293  	}
  1294  	children, ok := val.(map[string]interface{})
  1295  	if !ok {
  1296  		return fmt.Errorf("[buildQueryMap] expected type 'map[string]interface{}' for key '%s', but got '%T'", key, val)
  1297  	}
  1298  
  1299  	return buildQueryMap(children, keys[1:], value)
  1300  }
  1301  
  1302  // isPort 变量值是否端口号(1~65535).
  1303  func isPort(val interface{}) bool {
  1304  	if isInt(val) {
  1305  		port := toInt(val)
  1306  		if port > 0 && port < 65536 {
  1307  			return true
  1308  		}
  1309  	}
  1310  
  1311  	return false
  1312  }
  1313  
  1314  // similarText 计算两个字符串的相似度.
  1315  func similarText(str1, str2 string, len1, len2 int) int {
  1316  	var sum, max int
  1317  	pos1, pos2 := 0, 0
  1318  
  1319  	// Find the longest segment of the same section in two strings
  1320  	for i := 0; i < len1; i++ {
  1321  		for j := 0; j < len2; j++ {
  1322  			for l := 0; (i+l < len1) && (j+l < len2) && (str1[i+l] == str2[j+l]); l++ {
  1323  				if l+1 > max {
  1324  					max = l + 1
  1325  					pos1 = i
  1326  					pos2 = j
  1327  				}
  1328  			}
  1329  		}
  1330  	}
  1331  
  1332  	if sum = max; sum > 0 {
  1333  		if pos1 > 0 && pos2 > 0 {
  1334  			sum += similarText(str1, str2, pos1, pos2)
  1335  		}
  1336  		if (pos1+max < len1) && (pos2+max < len2) {
  1337  			s1 := []byte(str1)
  1338  			s2 := []byte(str2)
  1339  			sum += similarText(string(s1[pos1+max:]), string(s2[pos2+max:]), len1-pos1-max, len2-pos2-max)
  1340  		}
  1341  	}
  1342  
  1343  	return sum
  1344  }
  1345  
  1346  // GetVariateType 获取变量类型.
  1347  func GetVariateType(v interface{}) string {
  1348  	return fmt.Sprintf("%T", v)
  1349  }
  1350  
  1351  // GetVariatePointerAddr 获取变量的指针地址.
  1352  func GetVariatePointerAddr(val interface{}) int64 {
  1353  	var p string
  1354  	v := reflect.ValueOf(val)
  1355  	switch v.Kind() {
  1356  	case reflect.Ptr: //变量是指针
  1357  		p = fmt.Sprintf("%p", val)
  1358  	default:
  1359  		p = fmt.Sprintf("%p", &val)
  1360  	}
  1361  
  1362  	res, _ := hex2Dec(p)
  1363  	return res
  1364  }
  1365  
  1366  // IsPointer 检查变量是否指针类型;
  1367  // notNil 是否检查变量非nil.
  1368  func IsPointer(val interface{}, notNil bool) (res bool) {
  1369  	v := reflect.ValueOf(val)
  1370  	if v.Kind() == reflect.Ptr {
  1371  		if notNil == false || (notNil && val != nil) {
  1372  			res = true
  1373  		}
  1374  	}
  1375  
  1376  	return
  1377  }
  1378  
  1379  // VerifyFunc 验证是否函数,并且参数个数、类型是否正确.
  1380  // 返回有效的函数、有效的参数.
  1381  func VerifyFunc(f interface{}, args ...interface{}) (vf reflect.Value, vargs []reflect.Value, err error) {
  1382  	vf = reflect.ValueOf(f)
  1383  	if vf.Kind() != reflect.Func {
  1384  		return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %v is not the function", f)
  1385  	}
  1386  
  1387  	tf := vf.Type()
  1388  	_len := len(args)
  1389  	if tf.NumIn() != _len {
  1390  		return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %d number of the argument is incorrect", _len)
  1391  	}
  1392  
  1393  	vargs = make([]reflect.Value, _len)
  1394  	for i := 0; i < _len; i++ {
  1395  		typ := tf.In(i).Kind()
  1396  		if (typ != reflect.Interface) && (typ != reflect.TypeOf(args[i]).Kind()) {
  1397  			return reflect.ValueOf(nil), nil, fmt.Errorf("[VerifyFunc] %d-td argument`s type is incorrect", i+1)
  1398  		}
  1399  		vargs[i] = reflect.ValueOf(args[i])
  1400  	}
  1401  	return vf, vargs, nil
  1402  }
  1403  
  1404  // CallFunc 动态调用函数.
  1405  func CallFunc(f interface{}, args ...interface{}) (results []interface{}, err error) {
  1406  	vf, vargs, _err := VerifyFunc(f, args...)
  1407  	if _err != nil {
  1408  		return nil, _err
  1409  	}
  1410  	ret := vf.Call(vargs)
  1411  	_len := len(ret)
  1412  	results = make([]interface{}, _len)
  1413  	for i := 0; i < _len; i++ {
  1414  		results[i] = ret[i].Interface()
  1415  	}
  1416  	return
  1417  }