我相信你所要求的没有意义(与 Swift 无关)。虽然我有兴趣被证明是错误的,但我不相信这可以用任何强类型语言合理地创建。 (编辑:继续我的研究,我相信这在具有一流多态性的语言中是可能的,但我不知道任何通用语言实际上具有此功能。)
let myClosure = {<S where S: MyProtocol, S: MySuperClass>(param: S) in ... }
您期望什么类型myClosure
成为?泛型创建抽象类型。在专门化之前,它不会成为真正的类型。所以myClosure
本身就是一个抽象类型。这就像请求一个抽象类的实例。 “抽象”的全部意义在于你无法构建一个。你能说的最好的就是myClosure
本身就是一种类型,您需要将其实例化为真实实例(但随后let
没有任何意义;你不let
types).
当你把它包裹在一个struct
,您真正要做的是创建一个抽象类型,在创建实例时将其专门化为实际类型。
现在,在我看来,有意义的(但目前看来不可能)是这样的:
typealias Mapping<S> = S -> S
let identity: Mapping<Int> = { return $0 }
这是有道理的,因为您正在定义一个抽象类型(Mapping
),然后实例化一个具体类型Mapping<Int>
。很遗憾,typealias
目前似乎不支持泛型,所以struct
可能是我们拥有的最好的工具。
请注意,虽然typealias
是一个半身像,显然可以专门化函数变量本身。我知道,这不是一个闭包,但在某些相同的情况下可能很有用。
func Identity<T>(i:T) -> T {
return i
}
let identityInt:(Int -> Int) = Identity
identityInt(1) // => 1
使用它来进一步探讨抽象类型的问题,请考虑:
func Identity<T>(i:T) -> T { return i }
let x = Identity
这无法编译并出现错误:
error: cannot convert the expression's type '(T) -> T' to type '(T) -> T'
那是因为类型(T) -> T
不是一种具体类型,所以你不能叫它x
。比较一下identityInt
,我明确地将其专门化为具体类型,然后可以构造。