github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zutil/utils.go (about) 1 // Package zutil daily development helper functions 2 package zutil 3 4 import ( 5 "fmt" 6 "os" 7 "runtime" 8 "strings" 9 "time" 10 ) 11 12 type ( 13 // Stack uintptr array 14 Stack []uintptr 15 // Nocmp is an uncomparable struct 16 Nocmp [0]func() 17 namedArgs struct { 18 arg interface{} 19 name string 20 } 21 ) 22 23 // Named creates a named argument 24 func Named(name string, arg interface{}) interface{} { 25 return namedArgs{ 26 name: name, 27 arg: arg, 28 } 29 } 30 31 const ( 32 maxStackDepth = 1 << 5 33 ) 34 35 // WithRunContext function execution time and memory 36 func WithRunContext(handler func()) (time.Duration, uint64) { 37 start, mem := time.Now(), runtime.MemStats{} 38 runtime.ReadMemStats(&mem) 39 curMem := mem.Alloc 40 handler() 41 runtime.ReadMemStats(&mem) 42 return time.Since(start), mem.Alloc - curMem 43 } 44 45 // IfVal Simulate ternary calculations, pay attention to handling no variables or indexing problems 46 func IfVal(condition bool, trueVal, falseVal interface{}) interface{} { 47 if condition { 48 return trueVal 49 } 50 return falseVal 51 } 52 53 // TryCatch exception capture 54 func TryCatch(fn func() error) (err error) { 55 defer func() { 56 if recoverErr := recover(); recoverErr != nil { 57 if e, ok := recoverErr.(error); ok { 58 err = e 59 } else { 60 err = fmt.Errorf("%v", recoverErr) 61 } 62 } 63 }() 64 err = fn() 65 return 66 } 67 68 // Deprecated: please use zerror.TryCatch 69 // Try exception capture 70 func Try(fn func(), catch func(e interface{}), finally ...func()) { 71 if len(finally) > 0 { 72 defer func() { 73 finally[0]() 74 }() 75 } 76 defer func() { 77 if err := recover(); err != nil { 78 if catch != nil { 79 catch(err) 80 } else { 81 panic(err) 82 } 83 } 84 }() 85 fn() 86 } 87 88 // Deprecated: please use zerror.Panic 89 // CheckErr Check Err 90 func CheckErr(err error, exit ...bool) { 91 if err != nil { 92 if len(exit) > 0 && exit[0] { 93 fmt.Println(err) 94 os.Exit(1) 95 return 96 } 97 panic(err) 98 } 99 } 100 101 func Callers(skip ...int) Stack { 102 var ( 103 pcs [maxStackDepth]uintptr 104 n = 0 105 ) 106 if len(skip) > 0 { 107 n += skip[0] 108 } 109 return pcs[:runtime.Callers(n, pcs[:])] 110 } 111 112 func (s Stack) Format(f func(fn *runtime.Func, file string, line int) bool) { 113 if s == nil { 114 return 115 } 116 for _, p := range s { 117 if fn := runtime.FuncForPC(p - 1); fn != nil { 118 file, line := fn.FileLine(p - 1) 119 name := fn.Name() 120 if !strings.HasSuffix(file, "_test.go") && strings.Contains(name, "github.com/sohaha") { 121 continue 122 } 123 if !f(fn, file, line) { 124 break 125 } 126 } 127 } 128 }