聊聊dubbo-go-proxy的jtypes

本文主要研究一下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/[email protected]/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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章