github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/internal/reflect/convert.go (about)

     1  package reflect
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  )
     7  
     8  // 转换系列函数
     9  
    10  // ToTypePtr 将一个非指针的interface{}转换为他的指针底层表示
    11  // Bool表示是否非指针类型
    12  func ToTypePtr(v interface{}) (interface{}, bool) {
    13  	typ := reflect.TypeOf(v)
    14  	if typ.Kind() == reflect.Ptr {
    15  		return v, false
    16  	}
    17  	// Map/Chan 的eface data指针是双重指针(**hmap),要做特殊处理
    18  	if typ.Kind() == reflect.Map {
    19  		ptr := (*[2]unsafe.Pointer)(unsafe.Pointer(&v))[1]
    20  		inter := typeToEfaceNoNew(reflect.PtrTo(typ), nil)
    21  		return *(*interface{})(unsafe.Pointer(&Eface{
    22  			typ:  (*[2]unsafe.Pointer)(unsafe.Pointer(&inter))[0],
    23  			data: unsafe.Pointer(&ptr),
    24  		})), true
    25  	}
    26  	return reflect.New(typ).Interface(), true
    27  }
    28  
    29  // ToValueTypeEface 如果reflect.Value为nil则返回可以和nil比较的interface{}
    30  func ToValueTypeEface(val reflect.Value) interface{} {
    31  	eface := (*[2]uintptr)(unsafe.Pointer(&val))
    32  	if eface[0] == 0 && eface[1] == 0 {
    33  		return nil
    34  	}
    35  	return val.Interface()
    36  }