gitee.com/quant1x/engine@v1.8.4/labs/reflect.go (about) 1 package labs 2 3 import ( 4 "fmt" 5 "gitee.com/quant1x/engine/factors" 6 "reflect" 7 "strings" 8 "sync" 9 "unsafe" 10 ) 11 12 //go:linkname typelinks2 reflect.typelinks 13 func typelinks2() (sections []unsafe.Pointer, offset [][]int32) 14 15 //go:linkname resolveTypeOff reflect.resolveTypeOff 16 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 17 18 var ( 19 typeOnce sync.Once 20 types = map[string]reflect.Type{} 21 packages = map[string]map[string]reflect.Type{} 22 ) 23 24 type emptyInterface struct { 25 typ unsafe.Pointer 26 word unsafe.Pointer 27 } 28 29 func loadGoTypes() { 30 fia := reflect.TypeOf((*factors.Feature)(nil)).Elem() 31 var obj interface{} = reflect.TypeOf(0) 32 sections, offset := typelinks2() 33 for i, offs := range offset { 34 rodata := sections[i] 35 for _, off := range offs { 36 (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off) 37 typ := obj.(reflect.Type) 38 if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { 39 loadedType := typ.Elem() 40 pkgTypes := packages[loadedType.PkgPath()] 41 if pkgTypes == nil { 42 pkgTypes = map[string]reflect.Type{} 43 packages[loadedType.PkgPath()] = pkgTypes 44 } 45 //types[typeString] = loadedType 46 pkgPath := loadedType.PkgPath() 47 typeName := loadedType.Name() 48 //typeString := loadedType.String() 49 //fmt.Println(pkgPath, "=>", typeString, "=>", typeName) 50 structName := fmt.Sprintf("%s.%s", pkgPath, typeName) 51 types[structName] = loadedType 52 pkgTypes[loadedType.Name()] = loadedType 53 if strings.HasPrefix(pkgPath, "gitee.com/quant1x/engine") { 54 //fmt.Println(structName, "==>", loadedType.PkgPath()) 55 if reflect.PtrTo(loadedType).Implements(fia) { 56 fmt.Println("found", pkgPath, "==>", loadedType.String(), "==>", structName) 57 } 58 } 59 } 60 } 61 } 62 } 63 64 func lazyInit() { 65 loadGoTypes() 66 } 67 68 func FindImplements(u reflect.Type) (list []reflect.Type) { 69 typeOnce.Do(lazyInit) 70 for name, t := range types { 71 //fmt.Println(name) 72 if reflect.PtrTo(t).Implements(u) { 73 list = append(list, t) 74 } 75 _ = name 76 } 77 return 78 }