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  }