使用通用闭包进行类型匹配的奇怪行为

时间:2016-05-05 01:35:27

标签: swift generics closures

我在Xcode 7.3 Playground中使用此Swift代码时出现以下错误。

代码

/**  
 *  Represents a future value of type U, from a computation that has not been done yet.  
 */ 
public struct Promise<T, U> {
    var futureValue: T -> U

    public func then<T,U,V>(closure: U -> V) -> Promise<T, V> {
        return Promise<T, V>(futureValue: {
            input in
            let value = futureValue(input)
            return closure(value)
        })
    } 
}

错误

error: cannot invoke value of type 'T -> U' with argument list '((T))'
        let value = futureValue(input)

这看起来应该有效,因为类型在我的定义中匹配。可能导致这种行为的原因是什么?

1 个答案:

答案 0 :(得分:2)

public func then<T,U,V>(closure: U -> V) -> Promise<T, V> { ... }

本地通用占位符T, U 隐藏(或 shadow

中的通用占位符
public struct Promise<T, U> { ... }

类型定义。您的方法定义等同于

public func then<T1,U1,V>(closure: U1 -> V) -> Promise<T1, V> {
    return Promise<T1, V>(futureValue: {
        input in
        let value = futureValue(input)
        return closure(value)
    })
}

然后显示更易理解的错误消息

error: cannot invoke value of type 'T -> U' with argument list '((T1))'

解决方案很简单:只需从通用占位符中省略TU即可 在方法定义中列出,这些是自动继承的 struct Promise。另请注意futureValue属性必须 通过闭包内的self引用:

public func then<V>(closure: U -> V) -> Promise<T, V> {
    return Promise<T, V>(futureValue: {
        input in
        let value = self.futureValue(input)
        return closure(value)
    })
}