序
本文主要研究一下dubbo-go-proxy的jtypes
JTypeMapper
dubbo-go-proxy/pkg/common/constant/jtypes.go
// Object represents the java.lang.Object type type Object interface{} // JTypeMapper maps the java basic types to golang types var JTypeMapper = map[string]reflect.Type{ "string": reflect.TypeOf(""), "java.lang.String": reflect.TypeOf(""), "char": reflect.TypeOf(""), "short": reflect.TypeOf(int32(0)), "int": reflect.TypeOf(int32(0)), "long": reflect.TypeOf(int64(0)), "float": reflect.TypeOf(float64(0)), "double": reflect.TypeOf(float64(0)), "boolean": reflect.TypeOf(true), "java.util.Date": reflect.TypeOf(time.Time{}), "date": reflect.TypeOf(time.Time{}), "object": reflect.TypeOf([]Object{}).Elem(), "java.lang.Object": reflect.TypeOf([]Object{}).Elem(), }
JTypeMapper定义了个map,key为java类型,value为golang的reflect.Type
mapTypes
dubbo-go-proxy/pkg/client/dubbo/mapper.go
func mapTypes(jType string, originVal interface{}) (interface{}, error) { targetType, ok := constant.JTypeMapper[jType] if !ok { return nil, errors.Errorf("Invalid parameter type: %s", jType) } switch targetType { case reflect.TypeOf(""): return cast.ToStringE(originVal) case reflect.TypeOf(int32(0)): return cast.ToInt32E(originVal) case reflect.TypeOf(int64(0)): return cast.ToInt64E(originVal) case reflect.TypeOf(float64(0)): return cast.ToFloat64E(originVal) case reflect.TypeOf(true): return cast.ToBoolE(originVal) case reflect.TypeOf(time.Time{}): return cast.ToBoolE(originVal) default: return originVal, nil } }
mapTypes方法先根据jType从JTypeMapper取出对应的golang的reflect.Type,然后挨个根据这个类型使用cast类库进行转换,转成golang的interface{}
caste.go
github.com/spf13/cast@v1.3.1/caste.go
// ToStringE casts an interface to a string type. func ToStringE(i interface{}) (string, error) { i = indirectToStringerOrError(i) switch s := i.(type) { case string: return s, nil case bool: return strconv.FormatBool(s), nil case float64: return strconv.FormatFloat(s, 'f', -1, 64), nil case float32: return strconv.FormatFloat(float64(s), 'f', -1, 32), nil case int: return strconv.Itoa(s), nil case int64: return strconv.FormatInt(s, 10), nil case int32: return strconv.Itoa(int(s)), nil case int16: return strconv.FormatInt(int64(s), 10), nil case int8: return strconv.FormatInt(int64(s), 10), nil case uint: return strconv.FormatUint(uint64(s), 10), nil case uint64: return strconv.FormatUint(uint64(s), 10), nil case uint32: return strconv.FormatUint(uint64(s), 10), nil case uint16: return strconv.FormatUint(uint64(s), 10), nil case uint8: return strconv.FormatUint(uint64(s), 10), nil case []byte: return string(s), nil case template.HTML: return string(s), nil case template.URL: return string(s), nil case template.JS: return string(s), nil case template.CSS: return string(s), nil case template.HTMLAttr: return string(s), nil case nil: return "", nil case fmt.Stringer: return s.String(), nil case error: return s.Error(), nil default: return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i) } }
github.com/spf13/cast提供了一系列的cast方法,用于将interface{}转换为指定的类型
小结
JTypeMapper定义了个map,key为java类型,value为golang的reflect.Type;mapTypes方法先根据jType从JTypeMapper取出对应的golang的reflect.Type,然后挨个根据这个类型使用cast类库进行转换,转成golang的interface{}。
doc
- dubbo-go-proxy
有疑问加站长微信联系(非本文作者)