amuz.es/src/infra/goutils@v0.1.3/runtime/reflect.go (about) 1 package runtime 2 3 import ( 4 "unsafe" 5 "reflect" 6 "fmt" 7 ) 8 9 //go:linkname typesByString reflect.typesByString 10 //go:nosplit 11 func typesByString(s string) []unsafe.Pointer 12 13 /* 14 TypeByString tries to find a reflect.Type corresponding to the type specified by 15 s. 16 It calls the unexported `reflect.typesByString` to do so. It will fail if 17 the type can't be found or if more than one type with the given name exist. 18 This relies on the following assumptions: 19 * The signature of `reflect.typesByString` must not change 20 * The value returned by `reflect.TypeOf(0)` is a `*reflect.rtype` 21 * The `reflect.Value` struct contains a `ptr` field of type `unsafe.Pointer` 22 */ 23 func TypeByString(s string) (reflect.Type, error) { 24 types := typesByString(s) 25 26 if len(types) == 0 { 27 return nil, fmt.Errorf("Type '%s' not found", s) 28 } 29 if len(types) > 1 { 30 return nil, fmt.Errorf("Type '%s' is ambiguous", s) 31 } 32 33 t := types[0] 34 35 pRtypeType := reflect.ValueOf(reflect.TypeOf(0)).Type() 36 rtype := reflect.New(pRtypeType).Elem() 37 38 ptr := unsafe.Pointer(reflect.ValueOf(rtype).FieldByName("ptr").Pointer()) 39 *(*unsafe.Pointer)(ptr) = t 40 41 typ := rtype.Interface().(reflect.Type) 42 return typ, nil 43 }