github.com/gogf/gf@v1.16.9/util/gutil/gutil.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  // Package gutil provides utility functions.
     8  package gutil
     9  
    10  import (
    11  	"fmt"
    12  	"github.com/gogf/gf/internal/empty"
    13  	"github.com/gogf/gf/util/gconv"
    14  	"reflect"
    15  )
    16  
    17  // Throw throws out an exception, which can be caught be TryCatch or recover.
    18  func Throw(exception interface{}) {
    19  	panic(exception)
    20  }
    21  
    22  // Try implements try... logistics using internal panic...recover.
    23  // It returns error if any exception occurs, or else it returns nil.
    24  func Try(try func()) (err error) {
    25  	defer func() {
    26  		if e := recover(); e != nil {
    27  			err = fmt.Errorf(`%v`, e)
    28  		}
    29  	}()
    30  	try()
    31  	return
    32  }
    33  
    34  // TryCatch implements try...catch... logistics using internal panic...recover.
    35  // It automatically calls function `catch` if any exception occurs ans passes the exception as an error.
    36  func TryCatch(try func(), catch ...func(exception error)) {
    37  	defer func() {
    38  		if exception := recover(); exception != nil && len(catch) > 0 {
    39  			if err, ok := exception.(error); ok {
    40  				catch[0](err)
    41  			} else {
    42  				catch[0](fmt.Errorf(`%v`, exception))
    43  			}
    44  		}
    45  	}()
    46  	try()
    47  }
    48  
    49  // IsEmpty checks given `value` empty or not.
    50  // It returns false if `value` is: integer(0), bool(false), slice/map(len=0), nil;
    51  // or else returns true.
    52  func IsEmpty(value interface{}) bool {
    53  	return empty.IsEmpty(value)
    54  }
    55  
    56  // Keys retrieves and returns the keys from given map or struct.
    57  func Keys(mapOrStruct interface{}) (keysOrAttrs []string) {
    58  	keysOrAttrs = make([]string, 0)
    59  	if m, ok := mapOrStruct.(map[string]interface{}); ok {
    60  		for k, _ := range m {
    61  			keysOrAttrs = append(keysOrAttrs, k)
    62  		}
    63  		return
    64  	}
    65  	var (
    66  		reflectValue reflect.Value
    67  		reflectKind  reflect.Kind
    68  	)
    69  	if v, ok := mapOrStruct.(reflect.Value); ok {
    70  		reflectValue = v
    71  	} else {
    72  		reflectValue = reflect.ValueOf(mapOrStruct)
    73  	}
    74  	reflectKind = reflectValue.Kind()
    75  	for reflectKind == reflect.Ptr {
    76  		if !reflectValue.IsValid() || reflectValue.IsNil() {
    77  			reflectValue = reflect.New(reflectValue.Type().Elem()).Elem()
    78  			reflectKind = reflectValue.Kind()
    79  		} else {
    80  			reflectValue = reflectValue.Elem()
    81  			reflectKind = reflectValue.Kind()
    82  		}
    83  	}
    84  	switch reflectKind {
    85  	case reflect.Map:
    86  		for _, k := range reflectValue.MapKeys() {
    87  			keysOrAttrs = append(keysOrAttrs, gconv.String(k.Interface()))
    88  		}
    89  	case reflect.Struct:
    90  		var (
    91  			fieldType   reflect.StructField
    92  			reflectType = reflectValue.Type()
    93  		)
    94  		for i := 0; i < reflectValue.NumField(); i++ {
    95  			fieldType = reflectType.Field(i)
    96  			if fieldType.Anonymous {
    97  				keysOrAttrs = append(keysOrAttrs, Keys(reflectValue.Field(i))...)
    98  			} else {
    99  				keysOrAttrs = append(keysOrAttrs, fieldType.Name)
   100  			}
   101  		}
   102  	}
   103  	return
   104  }
   105  
   106  // Values retrieves and returns the values from given map or struct.
   107  func Values(mapOrStruct interface{}) (values []interface{}) {
   108  	values = make([]interface{}, 0)
   109  	if m, ok := mapOrStruct.(map[string]interface{}); ok {
   110  		for _, v := range m {
   111  			values = append(values, v)
   112  		}
   113  		return
   114  	}
   115  	var (
   116  		reflectValue reflect.Value
   117  		reflectKind  reflect.Kind
   118  	)
   119  	if v, ok := mapOrStruct.(reflect.Value); ok {
   120  		reflectValue = v
   121  	} else {
   122  		reflectValue = reflect.ValueOf(mapOrStruct)
   123  	}
   124  	reflectKind = reflectValue.Kind()
   125  	for reflectKind == reflect.Ptr {
   126  		reflectValue = reflectValue.Elem()
   127  		reflectKind = reflectValue.Kind()
   128  	}
   129  	switch reflectKind {
   130  	case reflect.Map:
   131  		for _, k := range reflectValue.MapKeys() {
   132  			values = append(values, reflectValue.MapIndex(k).Interface())
   133  		}
   134  	case reflect.Struct:
   135  		var (
   136  			fieldType   reflect.StructField
   137  			reflectType = reflectValue.Type()
   138  		)
   139  		for i := 0; i < reflectValue.NumField(); i++ {
   140  			fieldType = reflectType.Field(i)
   141  			if fieldType.Anonymous {
   142  				values = append(values, Values(reflectValue.Field(i))...)
   143  			} else {
   144  				values = append(values, reflectValue.Field(i).Interface())
   145  			}
   146  		}
   147  	}
   148  	return
   149  }