From 36401a063dff888938cbda97853f2ec335ec38e7 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 19 Mar 2020 13:38:42 +0800 Subject: [PATCH] improve gutil.Dump, improve sqlite file searching when opening db file --- container/garray/garray_z_example_test.go | 54 ++++++--- database/gdb/gdb.go | 2 + database/gdb/gdb_driver_sqlite.go | 6 + net/ghttp/ghttp_client_request.go | 4 +- net/ghttp/ghttp_request_param_request.go | 139 +++++++++++----------- os/gmutex/gmutex_bench_test.go | 6 +- util/gconv/gconv.go | 1 - util/gutil/gutil.go | 35 ------ util/gutil/gutil_dump.go | 138 +-------------------- 9 files changed, 126 insertions(+), 259 deletions(-) diff --git a/container/garray/garray_z_example_test.go b/container/garray/garray_z_example_test.go index eace2f821..cca19b0da 100644 --- a/container/garray/garray_z_example_test.go +++ b/container/garray/garray_z_example_test.go @@ -8,51 +8,52 @@ package garray_test import ( "fmt" + "github.com/gogf/gf/frame/g" "github.com/gogf/gf/container/garray" ) -func Example_basic() { - // 创建普通的数组 +func Example_Basic() { + // A normal array. a := garray.New() - // 添加数据项 + // Adding items. for i := 0; i < 10; i++ { a.Append(i) } - // 获取当前数组长度 + // Print the array length. fmt.Println(a.Len()) - // 获取当前数据项列表 + // Print the array items. fmt.Println(a.Slice()) - // 获取指定索引项 + // Retrieve item by index. fmt.Println(a.Get(6)) - // 查找指定数据项是否存在 + // Check item existence. fmt.Println(a.Contains(6)) fmt.Println(a.Contains(100)) - // 在指定索引前插入数据项 + // Insert item before specified index. a.InsertAfter(9, 11) - // 在指定索引后插入数据项 + // Insert item after specified index. a.InsertBefore(10, 10) fmt.Println(a.Slice()) - // 修改指定索引的数据项 + // Modify item by index. a.Set(0, 100) fmt.Println(a.Slice()) - // 搜索数据项,返回搜索到的索引位置 + // Search item and return its index. fmt.Println(a.Search(5)) - // 删除指定索引的数据项 + // Remove item by index. a.Remove(0) fmt.Println(a.Slice()) - // 清空数组 + // Empty the array, removes all items of it. fmt.Println(a.Slice()) a.Clear() fmt.Println(a.Slice()) @@ -71,15 +72,23 @@ func Example_basic() { // [] } -func Example_rand() { +func Example_Rand() { array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}) - // 随机返回两个数据项(不删除) + + // Randomly retrieve and return 2 items from the array. + // It does not delete the items from array. fmt.Println(array.Rands(2)) + + // Randomly pick and return one item from the array. + // It deletes the picked up item from array. fmt.Println(array.PopRand()) } -func Example_pop() { +func Example_PopItem() { array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}) + + // Any Pop* functions pick, delete and return the item from array. + fmt.Println(array.PopLeft()) fmt.Println(array.PopLefts(2)) fmt.Println(array.PopRight()) @@ -92,7 +101,7 @@ func Example_pop() { // [7 8] } -func Example_merge() { +func Example_MergeArray() { array1 := garray.NewFrom([]interface{}{1, 2}) array2 := garray.NewFrom([]interface{}{3, 4}) slice1 := []interface{}{5, 6} @@ -110,3 +119,14 @@ func Example_merge() { // [1 2] // [1 2 1 2 3 4 5 6 7 8 9 0] } + +func Example_Filter() { + array1 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"}) + array2 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"}) + fmt.Printf("%#v\n", array1.FilterNil().Slice()) + fmt.Printf("%#v\n", array2.FilterEmpty().Slice()) + + // Output: + // []interface {}{0, 1, 2, "", []interface {}{}, "john"} + // []interface {}{1, 2, "john"} +} diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index 1c9936c96..fc5125530 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -11,6 +11,7 @@ import ( "database/sql" "errors" "fmt" + "github.com/gogf/gf/internal/intlog" "time" "github.com/gogf/gf/os/glog" @@ -370,6 +371,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error v := c.cache.GetOrSetFuncLock(node.String(), func() interface{} { sqlDb, err = c.DB.Open(node) if err != nil { + intlog.Printf("DB open failed: %v, %+v", err, node) return nil } if c.maxIdleConnCount > 0 { diff --git a/database/gdb/gdb_driver_sqlite.go b/database/gdb/gdb_driver_sqlite.go index a39335604..5a17fddeb 100644 --- a/database/gdb/gdb_driver_sqlite.go +++ b/database/gdb/gdb_driver_sqlite.go @@ -14,6 +14,7 @@ import ( "database/sql" "fmt" "github.com/gogf/gf/internal/intlog" + "github.com/gogf/gf/os/gfile" "github.com/gogf/gf/text/gstr" "strings" ) @@ -34,11 +35,16 @@ func (d *DriverSqlite) New(core *Core, node *ConfigNode) (DB, error) { // Open creates and returns a underlying sql.DB object for sqlite. func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) { var source string + var err error if config.LinkInfo != "" { source = config.LinkInfo } else { source = config.Name } + source, err = gfile.Search(source) + if err != nil { + return nil, err + } intlog.Printf("Open: %s", source) if db, err := sql.Open("sqlite3", source); err == nil { return db, nil diff --git a/net/ghttp/ghttp_client_request.go b/net/ghttp/ghttp_client_request.go index a032c89f4..6b45fa6b9 100644 --- a/net/ghttp/ghttp_client_request.go +++ b/net/ghttp/ghttp_client_request.go @@ -24,8 +24,8 @@ import ( // Get send GET request and returns the response object. // Note that the response object MUST be closed if it'll be never used. -func (c *Client) Get(url string) (*ClientResponse, error) { - return c.DoRequest("GET", url) +func (c *Client) Get(url string, data ...interface{}) (*ClientResponse, error) { + return c.DoRequest("GET", url, data...) } // Put send PUT request and returns the response object. diff --git a/net/ghttp/ghttp_request_param_request.go b/net/ghttp/ghttp_request_param_request.go index ac11ef034..89d31e898 100644 --- a/net/ghttp/ghttp_request_param_request.go +++ b/net/ghttp/ghttp_request_param_request.go @@ -12,14 +12,14 @@ import ( "github.com/gogf/gf/util/gconv" ) -// GetRequest retrieves and returns the parameter named passed from client as interface{}, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequest retrieves and returns the parameter named passed from client and +// custom params as interface{}, no matter what HTTP method the client is using. The +// parameter specifies the default value if the does not exist. // // GetRequest is one of the most commonly used functions for retrieving parameters. // -// Note that if there're multiple parameters with the same name, the parameters are retrieved and overwrote -// in order of priority: router < query < body < form < custom. +// Note that if there're multiple parameters with the same name, the parameters are +// retrieved and overwrote in order of priority: router < query < body < form < custom. func (r *Request) GetRequest(key string, def ...interface{}) interface{} { value := r.GetParam(key) if value == nil { @@ -46,127 +46,127 @@ func (r *Request) GetRequest(key string, def ...interface{}) interface{} { return value } -// GetRequestVar retrieves and returns the parameter named passed from client as *gvar.Var, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestVar retrieves and returns the parameter named passed from client and +// custom params as *gvar.Var, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestVar(key string, def ...interface{}) *gvar.Var { return gvar.New(r.GetRequest(key, def...)) } -// GetRequestString retrieves and returns the parameter named passed from client as string, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestString retrieves and returns the parameter named passed from client and +// custom params as string, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestString(key string, def ...interface{}) string { return r.GetRequestVar(key, def...).String() } -// GetRequestBool retrieves and returns the parameter named passed from client as bool, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestBool retrieves and returns the parameter named passed from client and +// custom params as bool, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestBool(key string, def ...interface{}) bool { return r.GetRequestVar(key, def...).Bool() } -// GetRequestInt retrieves and returns the parameter named passed from client as int, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestInt retrieves and returns the parameter named passed from client and +// custom params as int, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestInt(key string, def ...interface{}) int { return r.GetRequestVar(key, def...).Int() } -// GetRequestInt32 retrieves and returns the parameter named passed from client as int32, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestInt32 retrieves and returns the parameter named passed from client and +// custom params as int32, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestInt32(key string, def ...interface{}) int32 { return r.GetRequestVar(key, def...).Int32() } -// GetRequestInt64 retrieves and returns the parameter named passed from client as int64, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestInt64 retrieves and returns the parameter named passed from client and +// custom params as int64, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestInt64(key string, def ...interface{}) int64 { return r.GetRequestVar(key, def...).Int64() } -// GetRequestInts retrieves and returns the parameter named passed from client as []int, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestInts retrieves and returns the parameter named passed from client and +// custom params as []int, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestInts(key string, def ...interface{}) []int { return r.GetRequestVar(key, def...).Ints() } -// GetRequestUint retrieves and returns the parameter named passed from client as uint, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestUint retrieves and returns the parameter named passed from client and +// custom params as uint, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestUint(key string, def ...interface{}) uint { return r.GetRequestVar(key, def...).Uint() } -// GetRequestUint32 retrieves and returns the parameter named passed from client as uint32, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestUint32 retrieves and returns the parameter named passed from client and +// custom params as uint32, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestUint32(key string, def ...interface{}) uint32 { return r.GetRequestVar(key, def...).Uint32() } -// GetRequestUint64 retrieves and returns the parameter named passed from client as uint64, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestUint64 retrieves and returns the parameter named passed from client and +// custom params as uint64, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestUint64(key string, def ...interface{}) uint64 { return r.GetRequestVar(key, def...).Uint64() } -// GetRequestFloat32 retrieves and returns the parameter named passed from client as float32, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestFloat32 retrieves and returns the parameter named passed from client and +// custom params as float32, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestFloat32(key string, def ...interface{}) float32 { return r.GetRequestVar(key, def...).Float32() } -// GetRequestFloat64 retrieves and returns the parameter named passed from client as float64, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestFloat64 retrieves and returns the parameter named passed from client and +// custom params as float64, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestFloat64(key string, def ...interface{}) float64 { return r.GetRequestVar(key, def...).Float64() } -// GetRequestFloats retrieves and returns the parameter named passed from client as []float64, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestFloats retrieves and returns the parameter named passed from client and +// custom params as []float64, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestFloats(key string, def ...interface{}) []float64 { return r.GetRequestVar(key, def...).Floats() } -// GetRequestArray retrieves and returns the parameter named passed from client as []string, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestArray retrieves and returns the parameter named passed from client and +// custom params as []string, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestArray(key string, def ...interface{}) []string { return r.GetRequestVar(key, def...).Strings() } -// GetRequestStrings retrieves and returns the parameter named passed from client as []string, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestStrings retrieves and returns the parameter named passed from client and +// custom params as []string, no matter what HTTP method the client is using. The parameter +// specifies the default value if the does not exist. func (r *Request) GetRequestStrings(key string, def ...interface{}) []string { return r.GetRequestVar(key, def...).Strings() } -// GetRequestInterfaces retrieves and returns the parameter named passed from client as []interface{}, -// no matter what HTTP method the client is using. The parameter specifies the default value -// if the does not exist. +// GetRequestInterfaces retrieves and returns the parameter named passed from client +// and custom params as []interface{}, no matter what HTTP method the client is using. The +// parameter specifies the default value if the does not exist. func (r *Request) GetRequestInterfaces(key string, def ...interface{}) []interface{} { return r.GetRequestVar(key, def...).Interfaces() } -// GetRequestMap retrieves and returns all parameters passed from client as map, -// no matter what HTTP method the client is using. The parameter specifies the keys -// retrieving from client parameters, the associated values are the default values if the client -// does not pass the according keys. +// GetRequestMap retrieves and returns all parameters passed from client and custom params +// as map, no matter what HTTP method the client is using. The parameter specifies +// the keys retrieving from client parameters, the associated values are the default values +// if the client does not pass the according keys. // // GetRequestMap is one of the most commonly used functions for retrieving parameters. // -// Note that if there're multiple parameters with the same name, the parameters are retrieved and overwrote -// in order of priority: router < query < body < form < custom. +// Note that if there're multiple parameters with the same name, the parameters are retrieved +// and overwrote in order of priority: router < query < body < form < custom. func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]interface{} { r.parseQuery() r.parseForm() @@ -231,10 +231,10 @@ func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]inte return m } -// GetRequestMapStrStr retrieves and returns all parameters passed from client as map[string]string, -// no matter what HTTP method the client is using. The parameter specifies the keys -// retrieving from client parameters, the associated values are the default values if the client -// does not pass. +// GetRequestMapStrStr retrieves and returns all parameters passed from client and custom +// params as map[string]string, no matter what HTTP method the client is using. The parameter +// specifies the keys retrieving from client parameters, the associated values are the +// default values if the client does not pass. func (r *Request) GetRequestMapStrStr(kvMap ...map[string]interface{}) map[string]string { requestMap := r.GetRequestMap(kvMap...) if len(requestMap) > 0 { @@ -247,10 +247,10 @@ func (r *Request) GetRequestMapStrStr(kvMap ...map[string]interface{}) map[strin return nil } -// GetRequestMapStrVar retrieves and returns all parameters passed from client as map[string]*gvar.Var, -// no matter what HTTP method the client is using. The parameter specifies the keys -// retrieving from client parameters, the associated values are the default values if the client -// does not pass. +// GetRequestMapStrVar retrieves and returns all parameters passed from client and custom +// params as map[string]*gvar.Var, no matter what HTTP method the client is using. The parameter +// specifies the keys retrieving from client parameters, the associated values are the +// default values if the client does not pass. func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[string]*gvar.Var { requestMap := r.GetRequestMap(kvMap...) if len(requestMap) > 0 { @@ -263,8 +263,9 @@ func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[strin return nil } -// GetRequestStruct retrieves all parameters passed from client no matter what HTTP method the client is using, -// and converts them to given struct object. Note that the parameter is a pointer to the struct object. +// GetRequestStruct retrieves all parameters passed from client and custom params no matter +// what HTTP method the client is using, and converts them to given struct object. Note that +// the parameter is a pointer to the struct object. // The optional parameter is used to specify the key to attribute mapping. func (r *Request) GetRequestStruct(pointer interface{}, mapping ...map[string]string) error { tagMap := structs.TagMapName(pointer, paramTagPriority, true) diff --git a/os/gmutex/gmutex_bench_test.go b/os/gmutex/gmutex_bench_test.go index 848b31c73..b54a7b5cf 100644 --- a/os/gmutex/gmutex_bench_test.go +++ b/os/gmutex/gmutex_bench_test.go @@ -59,7 +59,7 @@ func Benchmark_GMutex_TryLock(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { if gmu.TryLock() { - defer gmu.Unlock() + gmu.Unlock() } } }) @@ -77,7 +77,9 @@ func Benchmark_GMutex_RLockRUnlock(b *testing.B) { func Benchmark_GMutex_TryRLock(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - gmu.TryRLock() + if gmu.TryRLock() { + gmu.RUnlock() + } } }) } diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index c34d0a569..e4449d49e 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -122,7 +122,6 @@ func Convert(i interface{}, t string, params ...interface{}) interface{} { case "Duration", "time.Duration": return Duration(i) default: - return i } } diff --git a/util/gutil/gutil.go b/util/gutil/gutil.go index 750d59554..32487fd6a 100644 --- a/util/gutil/gutil.go +++ b/util/gutil/gutil.go @@ -8,44 +8,9 @@ package gutil import ( - "bytes" - "encoding/json" - "fmt" - "os" - "github.com/gogf/gf/internal/empty" - "github.com/gogf/gf/util/gconv" ) -// Dump prints variables to stdout with more manually readable. -func Dump(i ...interface{}) { - s := Export(i...) - if s != "" { - fmt.Println(s) - } -} - -// Export returns variables as a string with more manually readable. -func Export(i ...interface{}) string { - buffer := bytes.NewBuffer(nil) - for _, v := range i { - if b, ok := v.([]byte); ok { - buffer.Write(b) - } else { - if m := gconv.Map(v); m != nil && len(m) > 0 { - v = m - } - encoder := json.NewEncoder(buffer) - encoder.SetEscapeHTML(false) - encoder.SetIndent("", "\t") - if err := encoder.Encode(v); err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - } - } - } - return buffer.String() -} - // Throw throws out an exception, which can be caught be TryCatch or recover. func Throw(exception interface{}) { panic(exception) diff --git a/util/gutil/gutil_dump.go b/util/gutil/gutil_dump.go index 3b4fdc3d0..708cd5c32 100644 --- a/util/gutil/gutil_dump.go +++ b/util/gutil/gutil_dump.go @@ -4,19 +4,15 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package gutil provides utility functions. package gutil import ( "bytes" "encoding/json" "fmt" + "github.com/gogf/gf/util/gconv" "os" "reflect" - "strings" - - "github.com/gogf/gf/internal/empty" - "github.com/gogf/gf/util/gconv" ) // Dump prints variables to stdout with more manually readable. @@ -34,111 +30,17 @@ func Export(i ...interface{}) string { if b, ok := v.([]byte); ok { buffer.Write(b) } else { - rv := reflect.ValueOf(value) + rv := reflect.ValueOf(v) 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() } switch kind { - // If is type of array, it converts the value of even number index as its key and - // the value of odd number index as its corresponding value. - // Eg: - // []string{"k1","v1","k2","v2"} => map[string]interface{}{"k1":"v1", "k2":"v2"} - // []string{"k1","v1","k2"} => map[string]interface{}{"k1":"v1", "k2":nil} case reflect.Slice, reflect.Array: - length := rv.Len() - for i := 0; i < length; i += 2 { - if i+1 < length { - m[String(rv.Index(i).Interface())] = rv.Index(i + 1).Interface() - } else { - m[String(rv.Index(i).Interface())] = nil - } - } - case reflect.Map: - ks := rv.MapKeys() - for _, k := range ks { - m[String(k.Interface())] = rv.MapIndex(k).Interface() - } - case reflect.Struct: - // Map converting interface check. - if v, ok := value.(apiMapStrAny); ok { - return v.MapStrAny() - } - rt := rv.Type() - name := "" - tagArray := structTagPriority - switch len(tags) { - case 0: - // No need handle. - case 1: - tagArray = append(strings.Split(tags[0], ","), structTagPriority...) - default: - tagArray = append(tags, structTagPriority...) - } - var rtField reflect.StructField - var rvField reflect.Value - var rvKind reflect.Kind - for i := 0; i < rv.NumField(); i++ { - rtField = rt.Field(i) - rvField = rv.Field(i) - // Only convert the public attributes. - fieldName := rtField.Name - if !utils.IsLetterUpper(fieldName[0]) { - continue - } - name = "" - fieldTag := rtField.Tag - for _, tag := range tagArray { - if name = fieldTag.Get(tag); name != "" { - break - } - } - if name == "" { - name = strings.TrimSpace(fieldName) - } else { - // Support json tag feature: -, omitempty - name = strings.TrimSpace(name) - if name == "-" { - continue - } - array := strings.Split(name, ",") - if len(array) > 1 { - switch strings.TrimSpace(array[1]) { - case "omitempty": - if empty.IsEmpty(rvField.Interface()) { - continue - } else { - name = strings.TrimSpace(array[0]) - } - default: - name = strings.TrimSpace(array[0]) - } - } - } - if recursive { - rvKind = rvField.Kind() - if rvKind == reflect.Ptr { - rvField = rvField.Elem() - rvKind = rvField.Kind() - } - if rvKind == reflect.Struct { - for k, v := range doMapConvert(rvField.Interface(), recursive, tags...) { - m[k] = v - } - } else { - m[name] = rvField.Interface() - } - } else { - m[name] = rvField.Interface() - } - } - default: - return nil - } - if m := gconv.Map(v); m != nil && len(m) > 0 { - v = m + v = gconv.Interfaces(v) + case reflect.Map, reflect.Struct: + v = gconv.Map(v) } encoder := json.NewEncoder(buffer) encoder.SetEscapeHTML(false) @@ -150,33 +52,3 @@ func Export(i ...interface{}) string { } return buffer.String() } - -// Throw throws out an exception, which can be caught be TryCatch or recover. -func Throw(exception interface{}) { - panic(exception) -} - -// TryCatch implements try...catch... logistics. -func TryCatch(try func(), catch ...func(exception interface{})) { - if len(catch) > 0 { - // If is given, it's used to handle the exception. - defer func() { - if e := recover(); e != nil { - catch[0](e) - } - }() - } else { - // If no function passed, it filters the exception. - defer func() { - recover() - }() - } - try() -} - -// IsEmpty checks given empty or not. -// It returns false if is: integer(0), bool(false), slice/map(len=0), nil; -// or else returns true. -func IsEmpty(value interface{}) bool { - return empty.IsEmpty(value) -}