github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/internal/reflect/reflect.go (about) 1 package reflect 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type Eface struct { 9 typ unsafe.Pointer 10 data unsafe.Pointer 11 } 12 13 type Iface struct { 14 itab unsafe.Pointer 15 data unsafe.Pointer 16 } 17 18 func RealType(value reflect.Value) reflect.Value { 19 if value.Kind() != reflect.Interface { 20 return value 21 } 22 return RealType(reflect.ValueOf(value.Interface())) 23 } 24 25 // FuncInputTypeListReturnValue 返回函数的输入参数类型列表,空接口切片表示 26 // directNew是一个过滤器回调函数, 返回true指示new的类型是其原始类型, 返回false则根据是否指针类型来返回不同的数据 27 // 28 // Example 29 // if directNew() == true { Input(*reflect.Value) Exec -> return new(*reflect.Value)} 30 // if directNew() == false { Input(reflect.Value) Exec -> tmp := new(reflect.Value) -> return *tmp} 31 // if directNew() == false { Input(*reflect.Value) Exec -> tmp := new(reflect.Value) -> return tmp} 32 func FuncInputTypeListReturnValue(tList []reflect.Type, start int, directNew func(i int) bool, skipInter bool) []reflect.Value { 33 if (tList != nil && len(tList) == 0) || start >= len(tList) { 34 return nil 35 } 36 result := make([]reflect.Value, 0, len(tList)-start) 37 for index, typ := range tList { 38 if index < start { 39 continue 40 } 41 if directNew != nil && directNew(index) { 42 result = append(result, reflect.New(typ).Elem()) 43 continue 44 } 45 if typ.Kind() == reflect.Interface { 46 if skipInter { 47 result = append(result, reflect.ValueOf(nil)) 48 } else { 49 result = append(result, reflect.New(typ)) 50 } 51 continue 52 } 53 // 非指针的类型 54 if typ.Kind() != reflect.Ptr { 55 result = append(result, reflect.New(typ).Elem()) 56 continue 57 } 58 result = append(result, reflect.New(typ.Elem())) 59 } 60 return result 61 } 62 63 // FuncOutputTypeList 返回函数的返回值类型列表,空接口切片表示 64 // directNew是一个过滤器回调函数, 返回true指示new的类型是其原始类型, 返回false则根据是否指针类型来返回不同的数据 65 // 66 // Example 67 // if directNew() == true { Input(*reflect.Value) Exec -> return new(*reflect.Value)} 68 // if directNew() == false { Input(reflect.Value) Exec -> tmp := new(reflect.Value) -> return *tmp} 69 // if directNew() == false { Input(*reflect.Value) Exec -> tmp := new(reflect.Value) -> return tmp} 70 func FuncOutputTypeList(tList []reflect.Type, directNew func(i int) bool, skipInter bool) []interface{} { 71 if tList != nil && len(tList) == 0 { 72 return nil 73 } 74 result := make([]interface{}, 0, len(tList)) 75 for index, typ := range tList { 76 if directNew != nil && directNew(index) { 77 result = append(result, reflect.New(typ).Elem().Interface()) 78 continue 79 } 80 if typ.Kind() == reflect.Interface { 81 if skipInter { 82 result = append(result, nil) 83 } else { 84 result = append(result, reflect.New(typ).Interface()) 85 } 86 continue 87 } 88 // 非指针类型 89 if typ.Kind() != reflect.Ptr { 90 result = append(result, reflect.New(typ).Elem().Interface()) 91 continue 92 } 93 result = append(result, reflect.New(typ.Elem()).Interface()) 94 } 95 return result 96 } 97 98 // 将reflect.Type中携带的类型信息转换为efce的类型信息 99 // 会重新创建数据并修正eface data指针 100 func typeToEfaceNew(typ reflect.Type) interface{} { 101 iface := (*[2]unsafe.Pointer)(unsafe.Pointer(&typ)) 102 // Map/Chan 的eface data指针是双重指针,要做特殊处理 103 if typ.Kind() == reflect.Map { 104 return *(*interface{})(unsafe.Pointer(&Eface{ 105 typ: iface[1], 106 data: unsafe.Pointer(reflect.MakeMap(typ).Pointer()), 107 })) 108 } 109 return *(*interface{})(unsafe.Pointer(&Eface{ 110 typ: iface[1], 111 data: unsafe.Pointer(reflect.New(typ).Pointer()), 112 })) 113 } 114 115 // 将reflect.Type中携带的类型信息转换为efce的类型信息 116 // 不会会重新创建数据 117 func typeToEfaceNoNew(typ reflect.Type, val interface{}) interface{} { 118 iface := (*[2]unsafe.Pointer)(unsafe.Pointer(&typ)) 119 // Map/Chan 的eface data指针是双重指针,要做特殊处理 120 if typ.Kind() == reflect.Map { 121 return *(*interface{})(unsafe.Pointer(&Eface{ 122 typ: iface[1], 123 data: unsafe.Pointer(reflect.ValueOf(val).Pointer()), 124 })) 125 } 126 return *(*interface{})(unsafe.Pointer(&Eface{ 127 typ: iface[1], 128 data: (*[2]unsafe.Pointer)(unsafe.Pointer(&val))[1], 129 })) 130 } 131 132 // InterDataPointer 获得val对应eface-data指针的值 133 func InterDataPointer(val interface{}) unsafe.Pointer { 134 return (*Eface)(unsafe.Pointer(&val)).data 135 } 136 137 // DeepEqualNotType 主要用于比较 138 func DeepEqualNotType(x, y interface{}) bool { 139 if x == nil && y == nil { 140 return true 141 } else if x == nil || y == nil { 142 return false 143 } 144 xValue := reflect.ValueOf(x) 145 yValue := reflect.ValueOf(y) 146 if xValue.Type() == reflect.TypeOf([]interface{}{0}) || yValue.Type() == reflect.TypeOf([]interface{}{0}) { 147 if xValue.Kind() != reflect.Slice || yValue.Kind() != reflect.Slice { 148 return false 149 } 150 return deepEqualNotTypeOnArray(xValue, yValue) 151 } else if xValue.Type() != yValue.Type() { 152 return false 153 } else { 154 return reflect.DeepEqual(x, y) 155 } 156 } 157 158 func deepEqualNotTypeOnArray(x, y reflect.Value) bool { 159 if x.Len() != y.Len() { 160 return false 161 } 162 var rangeN reflect.Value 163 var cmpN reflect.Value 164 if _, xOK := x.Interface().([]interface{}); xOK { 165 rangeN = x 166 cmpN = y 167 } else { 168 rangeN = y 169 cmpN = x 170 } 171 length := x.Len() 172 for i := 0; i < length; i++ { 173 rangeV := RealType(rangeN.Index(i)) 174 cmpV := RealType(cmpN.Index(i)) 175 if rangeV.Kind() == reflect.Slice && cmpV.Kind() == reflect.Slice { 176 deepEqualNotTypeOnArray(rangeV, cmpV) 177 continue 178 } 179 if !reflect.DeepEqual(rangeV.Interface(), cmpV.Interface()) { 180 return false 181 } 182 } 183 return true 184 }