package main
import (
"fmt"
"reflect"
)
func (s StructWithManyMethods) Func1(a int, b uint, c float64) {
fmt.Printf("func:Func1 a:%d b:%d c:%f \n", a, b, c)
}
func (s StructWithManyMethods) Func2(a string, b int, c int, d int) {
fmt.Printf("func:Func2 a:%s b:%d c:%d d:%d\n", a, b, c, d)
}
type StructWithManyMethods struct {
}
func (s StructWithManyMethods) CallMethod(n string, p []interface{}) {
method := reflect.ValueOf(s).MethodByName(n)
methodType := method.Type()
for i := 0; i < methodType.NumIn(); i++ {
in := methodType.In(i)
switch in.Kind() {
case reflect.Float32:
switch v := p[i].(type) {
case float64:
p[i] = float32(v)
case float32:
p[i] = float32(v)
case int:
p[i] = float32(v)
case uint:
p[i] = float32(v)
case int8:
p[i] = float32(v)
case uint8:
p[i] = float32(v)
case int16:
p[i] = float32(v)
case uint16:
p[i] = float32(v)
case int32:
p[i] = float32(v)
case uint32:
p[i] = float32(v)
case int64:
p[i] = float32(v)
case uint64:
p[i] = float32(v)
}
case reflect.Float64:
switch v := p[i].(type) {
case float64:
p[i] = float64(v)
case float32:
p[i] = float64(v)
case int:
p[i] = float64(v)
case uint:
p[i] = float64(v)
case int8:
p[i] = float64(v)
case uint8:
p[i] = float64(v)
case int16:
p[i] = float64(v)
case uint16:
p[i] = float64(v)
case int32:
p[i] = float64(v)
case uint32:
p[i] = float64(v)
case int64:
p[i] = float64(v)
case uint64:
p[i] = float64(v)
}
case reflect.Int:
switch v := p[i].(type) {
case float64:
p[i] = int(v)
case float32:
p[i] = int(v)
case int:
p[i] = int(v)
case uint:
p[i] = int(v)
case int8:
p[i] = int(v)
case uint8:
p[i] = int(v)
case int16:
p[i] = int(v)
case uint16:
p[i] = int(v)
case int32:
p[i] = int(v)
case uint32:
p[i] = int(v)
case int64:
p[i] = int(v)
case uint64:
p[i] = int(v)
}
case reflect.Uint:
switch v := p[i].(type) {
case float64:
p[i] = uint(v)
case float32:
p[i] = uint(v)
case int:
p[i] = uint(v)
case uint:
p[i] = uint(v)
case int8:
p[i] = uint(v)
case uint8:
p[i] = uint(v)
case int16:
p[i] = uint(v)
case uint16:
p[i] = uint(v)
case int32:
p[i] = uint(v)
case uint32:
p[i] = uint(v)
case int64:
p[i] = uint(v)
case uint64:
p[i] = uint(v)
}
case reflect.Int8:
switch v := p[i].(type) {
case float64:
p[i] = int8(v)
case float32:
p[i] = int8(v)
case int:
p[i] = int8(v)
case uint:
p[i] = int8(v)
case int8:
p[i] = int8(v)
case uint8:
p[i] = int8(v)
case int16:
p[i] = int8(v)
case uint16:
p[i] = int8(v)
case int32:
p[i] = int8(v)
case uint32:
p[i] = int8(v)
case int64:
p[i] = int8(v)
case uint64:
p[i] = int8(v)
}
case reflect.Uint8:
switch v := p[i].(type) {
case float64:
p[i] = uint8(v)
case float32:
p[i] = uint8(v)
case int:
p[i] = uint8(v)
case uint:
p[i] = uint8(v)
case int8:
p[i] = uint8(v)
case uint8:
p[i] = uint8(v)
case int16:
p[i] = uint8(v)
case uint16:
p[i] = uint8(v)
case int32:
p[i] = uint8(v)
case uint32:
p[i] = uint8(v)
case int64:
p[i] = uint8(v)
case uint64:
p[i] = uint8(v)
}
case reflect.Int16:
switch v := p[i].(type) {
case float64:
p[i] = int16(v)
case float32:
p[i] = int16(v)
case int:
p[i] = int16(v)
case uint:
p[i] = int16(v)
case int8:
p[i] = int16(v)
case uint8:
p[i] = int16(v)
case int16:
p[i] = int16(v)
case uint16:
p[i] = int16(v)
case int32:
p[i] = int16(v)
case uint32:
p[i] = int16(v)
case int64:
p[i] = int16(v)
case uint64:
p[i] = int16(v)
}
case reflect.Uint16:
switch v := p[i].(type) {
case float64:
p[i] = uint16(v)
case float32:
p[i] = uint16(v)
case int:
p[i] = uint16(v)
case uint:
p[i] = uint16(v)
case int8:
p[i] = uint16(v)
case uint8:
p[i] = uint16(v)
case int16:
p[i] = uint16(v)
case uint16:
p[i] = uint16(v)
case int32:
p[i] = uint16(v)
case uint32:
p[i] = uint16(v)
case int64:
p[i] = uint16(v)
case uint64:
p[i] = uint16(v)
}
case reflect.Int32:
switch v := p[i].(type) {
case float64:
p[i] = int32(v)
case float32:
p[i] = int32(v)
case int:
p[i] = int32(v)
case uint:
p[i] = int32(v)
case int8:
p[i] = int32(v)
case uint8:
p[i] = int32(v)
case int16:
p[i] = int32(v)
case uint16:
p[i] = int32(v)
case int32:
p[i] = int32(v)
case uint32:
p[i] = int32(v)
case int64:
p[i] = int32(v)
case uint64:
p[i] = int32(v)
}
case reflect.Uint32:
switch v := p[i].(type) {
case float64:
p[i] = uint32(v)
case float32:
p[i] = uint32(v)
case int:
p[i] = uint32(v)
case uint:
p[i] = uint32(v)
case int8:
p[i] = uint32(v)
case uint8:
p[i] = uint32(v)
case int16:
p[i] = uint32(v)
case uint16:
p[i] = uint32(v)
case int32:
p[i] = uint32(v)
case uint32:
p[i] = uint32(v)
case int64:
p[i] = uint32(v)
case uint64:
p[i] = uint32(v)
}
case reflect.Int64:
switch v := p[i].(type) {
case float64:
p[i] = int64(v)
case float32:
p[i] = int64(v)
case int:
p[i] = int64(v)
case uint:
p[i] = int64(v)
case int8:
p[i] = int64(v)
case uint8:
p[i] = int64(v)
case int16:
p[i] = int64(v)
case uint16:
p[i] = int64(v)
case int32:
p[i] = int64(v)
case uint32:
p[i] = int64(v)
case int64:
p[i] = int64(v)
case uint64:
p[i] = int64(v)
}
case reflect.Uint64:
switch v := p[i].(type) {
case float64:
p[i] = uint64(v)
case float32:
p[i] = uint64(v)
case int:
p[i] = uint64(v)
case uint:
p[i] = uint64(v)
case int8:
p[i] = uint64(v)
case uint8:
p[i] = uint64(v)
case int16:
p[i] = uint64(v)
case uint16:
p[i] = uint64(v)
case int32:
p[i] = uint64(v)
case uint32:
p[i] = uint64(v)
case int64:
p[i] = uint64(v)
case uint64:
p[i] = uint64(v)
}
}
}
parameterValues := make([]reflect.Value, 0)
for _, e := range p {
parameterValues = append(parameterValues, reflect.ValueOf(e))
}
method.Call(parameterValues)
}
func main() {
var s StructWithManyMethods
s.CallMethod("Func1", []interface{}{1.0, 2.0, 3})
s.CallMethod("Func2", []interface{}{"test", 1, 2, 3.0})
}
字符串
输出量:
func:Func1 a:1 b:2 c:3.000000
func:Func2 a:test b:1 c:2 d:3
型
因为我需要动态调用方法,但是参数来自不同的数据格式,这就导致需要转换数值类型。例如,在Golang中解析JSON时,不确定的数字类型被视为float64,尽管它可能应该是int。
代码看起来很糟糕,但它工作得很好。
我想知道是否有更好的方法来做到这一点。
1条答案
按热度按时间6vl6ewon1#
使用反射API转换值。
字符串
为了防止死机,这段代码在转换之前检查是否允许转换。
Run the code on the PlayGround!