泛型作为swift中闭包的参数

时间:2014-08-20 09:46:13

标签: swift

我无法将以下函数编写为闭包

func myfunc<S where S: MyProtocol, S: MySuperClass>(param: S) { ... }

我试过

let myClosure = {<S where S: MyProtocol, S: MySuperClass>(param: S) in ... }

但它不起作用。

有什么建议吗?

2 个答案:

答案 0 :(得分:16)

我相信你所要求的东西是没有意义的(与Swift无关)。虽然我对被证明是错误的感兴趣,但我不相信这可以用任何强类型语言合理地创建。 (编辑:继续我的研究,我相信这可能是一种具有一流多态性的语言,但我不知道任何具有此功能的通用语言。)

let myClosure = {<S where S: MyProtocol, S: MySuperClass>(param: S) in ... }

您期望myClosure是什么类型的?泛型创建抽象类型。在专业化之前它不会成为真正的类型。所以myClosure本身就是一个抽象类型。这就像要求抽象类的实例一样。 &#34;抽象&#34;的重点你是不是可以建造一个。你可以说最好的是myClosure本身就是一个你需要实例化到一个真实实例中的类型(但是let没有任何意义;你不会&#39;} t let种类型。)

当你将它包装在struct中时,你真正要做的就是创建一个抽象类型,在创建实例时,你将专门化为真实类型。

现在有意义的IMO(但目前似乎不可能),是这样的:

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进行比较,我将其明确专门化为具体类型,然后构建。

答案 1 :(得分:1)

您可以尝试在声明泛型类型的结构中包装闭包。类似的东西:

struct ClosureWrapper<S where S: MyClass, S: MyProtocol> {
    let myClosure = {(param: S) in ... }
}

当然,此时你的关闭也可能是一个正常的功能:P