本文次要钻研一下dubbo-go-proxy的jtypes

JTypeMapper

dubbo-go-proxy/pkg/common/constant/jtypes.go

// Object represents the java.lang.Object typetype Object interface{}// JTypeMapper maps the java basic types to golang typesvar 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