如何编写一个采用泛型类型参数的函数,但根据泛型对象的类型返回不同的类型?

时间:2016-07-31 18:37:01

标签: swift swift3 generic-type-argument

我试图在swift3中编写一个基本的插值函数。但是我遇到了很多错误。这显然不是使用泛型的正确方法,但也许我对它们的应用有一个基本的误解?

class func interpolate<T>(from: T, to: T, progress: CGFloat) -> T
{
    // Safety
    assert(progress >= 0 && progress <= 1, "Invalid progress value: \(progress)")

    if let from = from as? CGFloat, let to = to as? CGFloat
    {
        return from + (to - from) * progress // No + candidates produce the expected contextual result type 'T'
    }
    if let from = from as? CGPoint, let to = to as? CGPoint
    {
        var returnPoint = CGPoint()
        returnPoint.x     = from.x + (to.x-from.x) * progress
        returnPoint.y     = from.y + (to.y-from.y) * progress
        return returnPoint // Cannot convert return expression of type 'CGPoint' to return type 'T'
    }
    if let from = from as? CGRect, let to = to as? CGRect
    {
        var returnRect = CGRect()
        returnRect.origin.x     = from.origin.x + (to.origin.x-from.origin.x) * progress
        returnRect.origin.y     = from.origin.y + (to.origin.y-from.origin.y) * progress
        returnRect.size.width   = from.size.width + (to.size.width-from.size.width) * progress
        returnRect.size.height  = from.size.height + (to.size.height-from.size.height) * progress
        return returnRect // Cannot convert return expression of type 'CGRect' to return type 'T'
    }

    return nil // Nil is incompatible with return type 'T'
}

1 个答案:

答案 0 :(得分:2)

当您对几种不同类型执行相同的操作时,通用函数很有用。这基本上就是你在这里所拥有的。问题是您没有为您关心的两种类型定义操作,即CGPointCGRect

如果创建单独的函数来添加,减去和乘以这些类型,则可以使此通用函数有效。它将简化为

class func interpolate<T>(from: T, to: T, progress: CGFloat) -> T
{
    // Safety
    assert(0.0...1.0 ~= progress, "Invalid progress value: \(progress)")

    return from + (to - from) * progress
}