github.com/wangyougui/gf/v2@v2.6.5/internal/reflection/reflection.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/wangyougui/gf.
     6  
     7  // Package reflection provides some reflection functions for internal usage.
     8  package reflection
     9  
    10  import (
    11  	"reflect"
    12  )
    13  
    14  type OriginValueAndKindOutput struct {
    15  	InputValue  reflect.Value
    16  	InputKind   reflect.Kind
    17  	OriginValue reflect.Value
    18  	OriginKind  reflect.Kind
    19  }
    20  
    21  // OriginValueAndKind retrieves and returns the original reflect value and kind.
    22  func OriginValueAndKind(value interface{}) (out OriginValueAndKindOutput) {
    23  	if v, ok := value.(reflect.Value); ok {
    24  		out.InputValue = v
    25  	} else {
    26  		out.InputValue = reflect.ValueOf(value)
    27  	}
    28  	out.InputKind = out.InputValue.Kind()
    29  	out.OriginValue = out.InputValue
    30  	out.OriginKind = out.InputKind
    31  	for out.OriginKind == reflect.Ptr {
    32  		out.OriginValue = out.OriginValue.Elem()
    33  		out.OriginKind = out.OriginValue.Kind()
    34  	}
    35  	return
    36  }
    37  
    38  type OriginTypeAndKindOutput struct {
    39  	InputType  reflect.Type
    40  	InputKind  reflect.Kind
    41  	OriginType reflect.Type
    42  	OriginKind reflect.Kind
    43  }
    44  
    45  // OriginTypeAndKind retrieves and returns the original reflect type and kind.
    46  func OriginTypeAndKind(value interface{}) (out OriginTypeAndKindOutput) {
    47  	if value == nil {
    48  		return
    49  	}
    50  	if reflectType, ok := value.(reflect.Type); ok {
    51  		out.InputType = reflectType
    52  	} else {
    53  		if reflectValue, ok := value.(reflect.Value); ok {
    54  			out.InputType = reflectValue.Type()
    55  		} else {
    56  			out.InputType = reflect.TypeOf(value)
    57  		}
    58  	}
    59  	out.InputKind = out.InputType.Kind()
    60  	out.OriginType = out.InputType
    61  	out.OriginKind = out.InputKind
    62  	for out.OriginKind == reflect.Ptr {
    63  		out.OriginType = out.OriginType.Elem()
    64  		out.OriginKind = out.OriginType.Kind()
    65  	}
    66  	return
    67  }
    68  
    69  // ValueToInterface converts reflect value to its interface type.
    70  func ValueToInterface(v reflect.Value) (value interface{}, ok bool) {
    71  	if v.IsValid() && v.CanInterface() {
    72  		return v.Interface(), true
    73  	}
    74  	switch v.Kind() {
    75  	case reflect.Bool:
    76  		return v.Bool(), true
    77  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    78  		return v.Int(), true
    79  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    80  		return v.Uint(), true
    81  	case reflect.Float32, reflect.Float64:
    82  		return v.Float(), true
    83  	case reflect.Complex64, reflect.Complex128:
    84  		return v.Complex(), true
    85  	case reflect.String:
    86  		return v.String(), true
    87  	case reflect.Ptr:
    88  		return ValueToInterface(v.Elem())
    89  	case reflect.Interface:
    90  		return ValueToInterface(v.Elem())
    91  	default:
    92  		return nil, false
    93  	}
    94  }