我有一个通用函数,用于将目标设置为从地图中提取的值。目前,我对该函数支持的所有类型都有一个丑陋的大开关语句,但想知道是否有任何方法可以根据另一个接口的基础类型转换接口。
两个接口的类型不直接相关,这增加了一个复杂性。目标接口是另一个接口的引用(例如,如果目标是 *int,则另一个接口应转换为 int)。不要担心不遵循此模式的示例。
以下是我使用的函数:
if iface, isSet := config[name]; isSet {
if convert != nil {
var err error
if iface, err = convert(iface); err != nil {
return err
}
}
var isType bool
switch target := target.(type) {
case *string:
*target, isType = iface.(string)
case *bool:
*target, isType = iface.(bool)
case *int:
*target, isType = iface.(int)
case **int:
*target, isType = iface.(*int)
case *[]string:
*target, isType = iface.([]string)
case *strslice.StrSlice:
*target, isType = iface.([]string)
case *map[string]string:
*target, isType = iface.(map[string]string)
case *map[string]struct{}:
*target, isType = iface.(map[string]struct{})
case *time.Duration:
*target, isType = iface.(time.Duration)
case *nat.PortSet:
*target, isType = iface.(map[nat.Port]struct{})
case **container.HealthConfig:
*target, isType = iface.(*container.HealthConfig)
default:
return fmt.Errorf("target must be a reference")
}
if !isType {
t := reflect.TypeOf(target).String()
return fmt.Errorf("%s should be type %s", name, t[1:])
}
}
return nil
}
感谢您的帮助!
答案 0 :(得分:5)
使用反射 API:
// set sets the value pointed to target to value.
func set(target interface{}, value interface{}) bool {
t := reflect.ValueOf(target).Elem()
v := reflect.ValueOf(value)
if !v.Type().AssignableTo(t.Type()) {
return false
}
t.Set(v)
return true
}
在你的代码中使用这样的函数:
isType := set(target, iface)