github.com/456vv/valexa@v1.0.2-0.20200706152242-1fb922d71ce5/Reflect.go (about)

     1  package valexa
     2  import (
     3      "reflect"
     4      "fmt"
     5  )
     6  
     7  
     8  
     9  //ForMethod 遍历方法
    10  //	x interface{}     类型
    11  //	string            字符串
    12  func ForMethod(x interface{}) string {
    13      var t = reflect.TypeOf(x)
    14      var s string
    15      for i:=0; i<t.NumMethod(); i++ {
    16          tm := t.Method(i)
    17          s += fmt.Sprintf("%d %s %s\t\t= %v \n", tm.Index, tm.PkgPath, tm.Name, tm.Type)
    18     }
    19     return s
    20  }
    21  
    22  //ForType 遍历字段
    23  //	x interface{}     类型
    24  //	string            字符串
    25  func ForType(x interface{}) string {
    26      return forType(x, "")
    27  }
    28  func forType(x interface{}, str string) string {
    29      var (
    30          v, z reflect.Value
    31          f reflect.StructField
    32          t reflect.Type
    33          k interface{}
    34          s string
    35      )
    36  
    37      v = reflect.ValueOf(x)
    38      v = inDirect(v)
    39      if v.Kind() == reflect.Invalid || v.Kind() != reflect.Struct {
    40          s += fmt.Sprintf("无法解析(%s): %#v\r\n", v.Kind(), x)
    41          return s
    42      }
    43      t = v.Type()
    44      for i := 0; i < t.NumField(); i++ {
    45          f = t.Field(i)
    46          z = inDirect(v.Field(i))
    47          k = typeSelect(z)
    48          s += fmt.Sprintf("%s %v %v %v\t%v `%v` = %v\r\n", str, f.Index, f.PkgPath, f.Name, f.Type, f.Tag, k)
    49          if z.Kind() == reflect.Struct && z.CanInterface() {
    50              s += forType(z.Interface(), "    "+str)
    51          }
    52      }
    53      return s
    54  }
    55  
    56  
    57  
    58  //TypeSelect 类型选择
    59  //	v reflect.Value        映射一种未知类型的变量
    60  //	interface{}            读出v的值
    61  func TypeSelect(v reflect.Value) interface{} {
    62      return typeSelect(v)
    63  }
    64  func typeSelect(v reflect.Value) interface{} {
    65  
    66      switch v.Kind() {
    67          case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    68              return v.Int()
    69          case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    70              return v.Uint()
    71          case reflect.Float32, reflect.Float64:
    72              return v.Float()
    73          case reflect.Bool:
    74              return v.Bool()
    75          case reflect.Complex64, reflect.Complex128:
    76              return v.Complex()
    77  	    case reflect.Invalid:
    78              return nil
    79          case reflect.Slice, reflect.Array:
    80              if v.CanInterface() {
    81                  return v.Interface()
    82              }
    83              var t []interface{}
    84              for i:=0; i<v.Len(); i++ {
    85                  t = append(t, typeSelect(v.Index(i)))
    86              }
    87              return t
    88          default:
    89              if v.CanInterface() {
    90                  return v.Interface()
    91              }
    92              return v.String()
    93      }
    94  }
    95  
    96  //InDirect 指针到内存
    97  //	v reflect.Value        映射引用为真实内存地址
    98  //	reflect.Value          真实内存地址
    99  func InDirect(v reflect.Value) reflect.Value {
   100      return inDirect(v)
   101  }
   102  func inDirect(v reflect.Value) reflect.Value {
   103  	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {}
   104      return v
   105  }
   106  
   107  //DepthField 快速深入读取字段
   108  //  s interface{}        Struct
   109  //  ndex ... interface{} 字段
   110  //  field interface{}    字段
   111  //  err error            错误
   112  //  例:
   113  //  type A struct {
   114  //   B
   115  //  }
   116  //  type B struct {
   117  //   C
   118  //   F map[string]string
   119  //   G []string
   120  //  }
   121  //  type C struct {
   122  //   D int
   123  //  }
   124  //  func main(){
   125  //   a := A{}
   126  //      fidld, err := DepthField(a, "B", "C", "D")
   127  //      fmt.Println(fidld, err)
   128  //      //0 <nil>
   129  //     }
   130  func DepthField(s interface{}, index ... interface{}) (field interface{}, err error) {
   131      field = s
   132      for _, i := range index {
   133      	field, err = depthField(field, i)
   134          if err != nil {
   135          	return nil, err
   136          }
   137      }
   138  	return field, nil
   139  }
   140  
   141  func depthField(s interface{}, index interface{}) (interface{}, error) {
   142      sv := reflect.ValueOf(s)
   143      sid := InDirect(sv)
   144      var reflectValue reflect.Value
   145      switch sid.Kind() {
   146      case reflect.Struct:
   147      	reflectValue = sid.FieldByName(index.(string))
   148      case reflect.Map:
   149      	if sid.IsNil() {
   150       		return nil, fmt.Errorf("valexa: 该字段是 nil。错误的字段名为(%#v)", index)
   151    	 	}
   152      	reflectValue = sid.MapIndex(reflect.ValueOf(index))
   153      case reflect.Slice, reflect.Array:
   154      	if sid.Len() > index.(int) {
   155      		reflectValue = sid.Index(index.(int))
   156      	}
   157      default:
   158      	return nil, fmt.Errorf("valexa: 非结构类型,无法正确读取。错误的类型为(%s)", sid.Kind())
   159      }
   160      if reflectValue.Kind() == reflect.Invalid {
   161      	return nil, fmt.Errorf("valexa: 该字段不是有效。错误的字段名为(%#v)", index)
   162      }
   163      return TypeSelect(reflectValue), nil
   164  }