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

     1  package reflect
     2  
     3  import (
     4  	"reflect"
     5  	"sync"
     6  	"unsafe"
     7  )
     8  
     9  var (
    10  	// Any.Any的非Slice类型的缓存
    11  	cacheType sync.Map
    12  	// Any.Any的Slice类型缓存
    13  	cacheSliceType sync.Map
    14  )
    15  
    16  // CreateAnyStructOnElemType 通过数组/切片的元素类型
    17  // 创建Any字段类型为[]val.Type的struct
    18  // 返回的是其结构体的指针类型
    19  func CreateAnyStructOnElemType(val interface{}) interface{} {
    20  	eface := (*[2]uintptr)(unsafe.Pointer(&val))
    21  	var typ reflect.Type
    22  	// 查询有无缓存,缓存中有对应的*type结构则不需要创建
    23  	typVal, ok := cacheSliceType.Load(eface[0])
    24  	if !ok {
    25  		typ = reflect.StructOf([]reflect.StructField{
    26  			{Name: "Any", Type: reflect.SliceOf(reflect.TypeOf(val))},
    27  		})
    28  		cacheSliceType.Store(eface[0], typ)
    29  	} else {
    30  		typ = typVal.(reflect.Type)
    31  	}
    32  	ptrTyp := reflect.PtrTo(typ)
    33  	sVal := reflect.New(typ).Interface()
    34  	return typeToEfaceNoNew(ptrTyp, sVal)
    35  }
    36  
    37  // CreateAnyStructOnType 通过val的类型
    38  // 创建Any字段类型为val.Type的struct,返回值类型为结构体的指针
    39  func CreateAnyStructOnType(val interface{}) interface{} {
    40  	eface := (*[2]uintptr)(unsafe.Pointer(&val))
    41  	var typ reflect.Type
    42  	// 查询有无缓存,缓存中有对应的*type结构则不需要创建
    43  	typVal, ok := cacheType.Load(eface[0])
    44  	if !ok {
    45  		typ = reflect.StructOf([]reflect.StructField{
    46  			{Name: "Any", Type: reflect.TypeOf(val)},
    47  		})
    48  		cacheType.Store(eface[0], typ)
    49  	} else {
    50  		typ = typVal.(reflect.Type)
    51  	}
    52  	ptrTyp := reflect.PtrTo(typ)
    53  	sVal := reflect.New(typ).Interface()
    54  	return typeToEfaceNoNew(ptrTyp, sVal)
    55  }
    56  
    57  // 装配Any.Any的空接口表示
    58  func ComposeStructAnyEface(val interface{}, rawType reflect.Type) interface{} {
    59  	eface := (*Eface)(unsafe.Pointer(&val))
    60  	return typeToEfaceNoNew(rawType, *(*interface{})(unsafe.Pointer(&Eface{
    61  		typ:  (*[2]unsafe.Pointer)(unsafe.Pointer(&rawType))[1],
    62  		data: eface.data,
    63  	})))
    64  }