从另一种接口类型转换接口

时间:2021-04-28 16:08:33

标签: go interface casting type-inference

我有一个通用函数,用于将目标设置为从地图中提取的值。目前,我对该函数支持的所有类型都有一个丑陋的大开关语句,但想知道是否有任何方法可以根据另一个接口的基础类型转换接口。

两个接口的类型不直接相关,这增加了一个复杂性。目标接口是另一个接口的引用(例如,如果目标是 *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
}

感谢您的帮助!

1 个答案:

答案 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)