github.com/gogf/gf/v2@v2.7.4/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/gogf/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 }