|
@@ -0,0 +1,370 @@
|
|
|
+package tools
|
|
|
+
|
|
|
+import (
|
|
|
+ "bufio"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "io/ioutil"
|
|
|
+ "math/rand"
|
|
|
+ "os"
|
|
|
+ "os/exec"
|
|
|
+ "path"
|
|
|
+ "path/filepath"
|
|
|
+ "reflect"
|
|
|
+ "runtime"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+// 获取结构中的Name标签
|
|
|
+// 返回字典
|
|
|
+func StructTagNameMap(str interface{}, tag string) (ret map[string]string) {
|
|
|
+ ret = make(map[string]string)
|
|
|
+ s := reflect.TypeOf(str).Elem()
|
|
|
+ for i := 0; i < s.NumField(); i++ {
|
|
|
+ if s.Field(i).Tag.Get(tag) != "" {
|
|
|
+ ret[s.Field(i).Name] = s.Field(i).Tag.Get(tag) //将tag输出
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// 获取结构中的Name标签
|
|
|
+// 返回数组
|
|
|
+// Tag中为-号,则不显示
|
|
|
+func StructTagNameGroup(str interface{}, tag string) (ret []string) {
|
|
|
+ s := reflect.TypeOf(str).Elem()
|
|
|
+ for i := 0; i < s.NumField(); i++ {
|
|
|
+ if s.Field(i).Tag.Get(tag) != "-" {
|
|
|
+ ret = append(ret, s.Field(i).Name) //将tag输出
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// 判断文件或文件夹是否存在
|
|
|
+func IsExist(path string) bool {
|
|
|
+ _, err := os.Stat(path)
|
|
|
+ if err != nil {
|
|
|
+ if os.IsExist(err) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if os.IsNotExist(err) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ fmt.Println(err)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+// 调试信息输出
|
|
|
+func Debug(show bool, args ...interface{}) {
|
|
|
+ if show { // 调试信息可以通过全局变量,统一关闭
|
|
|
+ fmt.Println(args...)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 随机数
|
|
|
+func RndNum(max int) int {
|
|
|
+ rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
+ return rnd.Intn(100)
|
|
|
+}
|
|
|
+
|
|
|
+// 生成几位随机数的字符串
|
|
|
+func RandString(len int) string {
|
|
|
+ r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
+ bytes := make([]byte, len)
|
|
|
+ for i := 0; i < len; i++ {
|
|
|
+ b := r.Intn(10) + 48
|
|
|
+ bytes[i] = byte(b)
|
|
|
+ }
|
|
|
+ return string(bytes)
|
|
|
+}
|
|
|
+
|
|
|
+// 生成重复字符
|
|
|
+func Repeat(str string, num int) (ret string) {
|
|
|
+ for i := 0; i < num; i++ {
|
|
|
+ ret = ret + str
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// 转换 --------------------------------------
|
|
|
+
|
|
|
+func StrToInt(str string) int {
|
|
|
+ i, e := strconv.Atoi(str)
|
|
|
+ if e != nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ return i
|
|
|
+}
|
|
|
+
|
|
|
+func StrToUInt(str string) uint {
|
|
|
+ i, e := strconv.Atoi(str)
|
|
|
+ if e != nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ return uint(i)
|
|
|
+}
|
|
|
+
|
|
|
+func UintToInt64(num uint) int64 {
|
|
|
+ return int64(num)
|
|
|
+}
|
|
|
+
|
|
|
+// 对Int数取绝对值
|
|
|
+func AbsByInt(num int) int {
|
|
|
+ if num < 0 {
|
|
|
+ return -num
|
|
|
+ }
|
|
|
+ return num
|
|
|
+}
|
|
|
+
|
|
|
+// 数值转字符
|
|
|
+func IntToStr(num int) string {
|
|
|
+ return strconv.Itoa(num)
|
|
|
+}
|
|
|
+
|
|
|
+// interface 转字符
|
|
|
+func InterfaceToStr(value interface{}) string {
|
|
|
+ if str, ok := value.(string); ok {
|
|
|
+ return str
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+// 字符串数组包含判断
|
|
|
+func StringIn(target string, str_array []string) bool {
|
|
|
+ sort.Strings(str_array)
|
|
|
+ index := sort.SearchStrings(str_array, target)
|
|
|
+ if index < len(str_array) && str_array[index] == target {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 随机字串
|
|
|
+func RndNonceStr() string {
|
|
|
+ str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
+ bytes := []byte(str)
|
|
|
+ result := []byte{}
|
|
|
+ r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
+ for i := 0; i < 32; i++ {
|
|
|
+ result = append(result, bytes[r.Intn(len(bytes))])
|
|
|
+ }
|
|
|
+ return string(result)
|
|
|
+}
|
|
|
+
|
|
|
+// 执行命令
|
|
|
+func Command(params []string) (string, error) {
|
|
|
+ var c *exec.Cmd
|
|
|
+ switch runtime.GOOS {
|
|
|
+ case "darwin":
|
|
|
+ case "windows":
|
|
|
+ para := append([]string{"/C"}, params[0:]...)
|
|
|
+ c = exec.Command("cmd", para...)
|
|
|
+ case "linux":
|
|
|
+ para := append([]string{"-c"}, params[0:]...)
|
|
|
+ c = exec.Command("bash", para...)
|
|
|
+ }
|
|
|
+
|
|
|
+ output, err := c.CombinedOutput()
|
|
|
+ return string(output), err
|
|
|
+}
|
|
|
+
|
|
|
+// 获取所有文件
|
|
|
+func AllFileByName(pathSeparator string, fileDir string, extFile string, hasDir bool) (ret []string) {
|
|
|
+ files, _ := ioutil.ReadDir(fileDir)
|
|
|
+
|
|
|
+ for _, onefile := range files {
|
|
|
+ if onefile.IsDir() {
|
|
|
+ // fmt.Println(onefile.Name())
|
|
|
+ //fmt.Println(tmpPrefix, onefile.Name(), "目录:")
|
|
|
+ if hasDir {
|
|
|
+ AllFileByName(pathSeparator, fileDir+pathSeparator+onefile.Name(), extFile, hasDir)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if strings.ToUpper(extFile) == strings.ToUpper(path.Ext(onefile.Name())) || extFile == "" {
|
|
|
+ ret = append(ret, onefile.Name())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 删除文件
|
|
|
+func RemoveFile(path string, fileList []string) {
|
|
|
+ for _, n := range fileList {
|
|
|
+ os.Remove(path + n)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 复制文件
|
|
|
+func CopyFile(srcFilePath string, dstFilePath string) (written int64, err error) {
|
|
|
+ srcFile, err := os.Open(srcFilePath)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Printf("打开源文件错误,错误信息=%v\n", err)
|
|
|
+ }
|
|
|
+ defer srcFile.Close()
|
|
|
+ reader := bufio.NewReader(srcFile)
|
|
|
+
|
|
|
+ dstFile, err := os.OpenFile(dstFilePath, os.O_WRONLY|os.O_CREATE, 0777)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Printf("打开目标文件错误,错误信息=%v\n", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ writer := bufio.NewWriter(dstFile)
|
|
|
+ defer dstFile.Close()
|
|
|
+ return io.Copy(writer, reader)
|
|
|
+}
|
|
|
+
|
|
|
+// 获取当前程序名
|
|
|
+func GetMeName() string {
|
|
|
+ return filepath.Base(os.Args[0])
|
|
|
+}
|
|
|
+
|
|
|
+// 获取字符长度
|
|
|
+// GetStrLength("这是中文,和ABC长度.😂")
|
|
|
+// 返回:表情符数量,汉字数量,英文数量
|
|
|
+func GetStrLength(str string) (mNum int, cNum int, eNum int) {
|
|
|
+ rs := []rune(str)
|
|
|
+ for i := 0; i < len(rs); i++ {
|
|
|
+ switch len(string(rs[i])) {
|
|
|
+ case 4:
|
|
|
+ mNum += 1
|
|
|
+ case 3:
|
|
|
+ cNum += 1
|
|
|
+ case 1:
|
|
|
+ eNum += 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return mNum, cNum, eNum // 表情符数量,汉字数量,英文数量
|
|
|
+}
|
|
|
+
|
|
|
+// 支持三元表达 -------------------------------------------------
|
|
|
+
|
|
|
+// callFn if args[i] == func, run it
|
|
|
+func callFn(f interface{}) interface{} {
|
|
|
+ if f != nil {
|
|
|
+ t := reflect.TypeOf(f)
|
|
|
+ if t.Kind() == reflect.Func && t.NumIn() == 0 {
|
|
|
+ function := reflect.ValueOf(f)
|
|
|
+ in := make([]reflect.Value, 0)
|
|
|
+ out := function.Call(in)
|
|
|
+ if num := len(out); num > 0 {
|
|
|
+ list := make([]interface{}, num)
|
|
|
+ for i, value := range out {
|
|
|
+ list[i] = value.Interface()
|
|
|
+ }
|
|
|
+ if num == 1 {
|
|
|
+ return list[0]
|
|
|
+ }
|
|
|
+ return list
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return f
|
|
|
+}
|
|
|
+
|
|
|
+func isZero(f interface{}) bool {
|
|
|
+ v := reflect.ValueOf(f)
|
|
|
+ switch v.Kind() {
|
|
|
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
+ return v.Int() == 0
|
|
|
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
+ return v.Uint() == 0
|
|
|
+ case reflect.Float32, reflect.Float64:
|
|
|
+ return v.Float() == 0
|
|
|
+ case reflect.String:
|
|
|
+ str := v.String()
|
|
|
+ if str == "" {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ zero, error := strconv.ParseFloat(str, 10)
|
|
|
+ if zero == 0 && error == nil {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ boolean, error := strconv.ParseBool(str)
|
|
|
+ return boolean == false && error == nil
|
|
|
+ default:
|
|
|
+ return false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// If - (a ? b : c) Or (a && b)
|
|
|
+// var a = If(20 > 50, true, false) // a = false
|
|
|
+// var b = Or(a, 100) // b = 100
|
|
|
+// var c = If(b, 50) // c = 50
|
|
|
+// var fn = If(c > 40, func(){ return "ok" }) // fn = "ok"
|
|
|
+
|
|
|
+func If(args ...interface{}) interface{} {
|
|
|
+ var condition = callFn(args[0])
|
|
|
+ if len(args) == 1 {
|
|
|
+ return condition
|
|
|
+ }
|
|
|
+ var trueVal = args[1]
|
|
|
+ var falseVal interface{}
|
|
|
+ if len(args) > 2 {
|
|
|
+ falseVal = args[2]
|
|
|
+ } else {
|
|
|
+ falseVal = nil
|
|
|
+ }
|
|
|
+ if condition == nil {
|
|
|
+ return callFn(falseVal)
|
|
|
+ } else if v, ok := condition.(bool); ok {
|
|
|
+ if v == false {
|
|
|
+ return callFn(falseVal)
|
|
|
+ }
|
|
|
+ } else if isZero(condition) {
|
|
|
+ return callFn(falseVal)
|
|
|
+ } else if v, ok := condition.(error); ok {
|
|
|
+ if v != nil {
|
|
|
+ fmt.Println(v)
|
|
|
+ return condition
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return callFn(trueVal)
|
|
|
+}
|
|
|
+
|
|
|
+// Or - (a || b)
|
|
|
+func Or(args ...interface{}) interface{} {
|
|
|
+ var condition = callFn(args[0])
|
|
|
+ if len(args) == 1 {
|
|
|
+ return condition
|
|
|
+ }
|
|
|
+ if condition == nil {
|
|
|
+ return callFn(args[1])
|
|
|
+ }
|
|
|
+ if v, ok := condition.(bool); ok {
|
|
|
+ if v == false {
|
|
|
+ return callFn(args[1])
|
|
|
+ }
|
|
|
+ } else if isZero(condition) {
|
|
|
+ return callFn(args[1])
|
|
|
+ } else if v, ok := condition.(error); ok {
|
|
|
+ if v != nil {
|
|
|
+ fmt.Println(v)
|
|
|
+ return condition
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return condition
|
|
|
+}
|
|
|
+
|
|
|
+// 将字符填满位数 str 要填充的字符 size 填充为多少位 addStr 填充什么字符
|
|
|
+func StrSetSize(str string, size int, addStr string) string {
|
|
|
+ var a string
|
|
|
+ if len(str) > size {
|
|
|
+ return str[0:size]
|
|
|
+ } else {
|
|
|
+ for i := 0; i < size-len(str); i++ {
|
|
|
+ a = a + addStr
|
|
|
+ }
|
|
|
+ return fmt.Sprintf("%s%s", str, a)
|
|
|
+ }
|
|
|
+}
|