reflection.go 2.6 KB

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