泛型作为快速闭包的参数 [英] generics as parameters to a closure in swift

查看:28
本文介绍了泛型作为快速闭包的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写以下函数作为闭包时遇到问题

I'm having trouble writing the following function as a closure

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

我试过了

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

但它不起作用.

有什么建议吗?

推荐答案

我相信你的要求毫无意义(与 Swift 无关).虽然我有兴趣被证明是错误的,但我不相信这可以用任何强类型语言合理地创建.(继续我的研究,我相信这在具有一流多态性的语言中是可能的,但我不知道任何实际具有此功能的通用语言.)

I believe what you're asking for can't make sense (having nothing to do with Swift). While I'm interested in being proven wrong, I don't believe this could be reasonably created in any strongly typed language. ( continuing my research, I believe this would be possible in a language with first-class polymorphism, but I am not aware of any general-use languages that actually have this feature.)

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

您希望 myClosure 是什么类型?泛型创建抽象类型.直到它被专门化,它才成为真正的类型.所以 myClosure 本身就是一个抽象类型.这就像要求一个抽象类的实例.抽象"的全部意义在于你不能构建一个.你能说的最好的是 myClosure 本身就是一种你需要实例化为一个真实实例的类型(但是 let 没有任何意义;你不要let 类型).

What type would you expect myClosure to be? A generic creates an abstract type. It does not become a real type until it is specialized. So myClosure would be of an abstract type itself. That's like asking for an instance of an abstract class. The whole point of "abstract" is you can't construct one. The best you could say would be that myClosure would itself be a type that you would need to instantiate into a real instance (but then let doesn't make any sense; you don't let types).

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

When you wrap this in a struct, what you're really doing is creating an abstract type that you will specialize into a real type when you create an instance.

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

Now what would make sense IMO (but appears currently to be impossible), is this:

typealias Mapping<S> = S -> S
let identity: Mapping<Int> = { return $0 }

这是有道理的,因为您正在定义一个抽象类型 (Mapping),然后实例化一个具体类型 Mapping.不幸的是,typealias 目前似乎不支持泛型,所以 struct 可能是我们拥有的最好的工具.

That makes sense because you're defining an abstract type (Mapping), but then instantiating a concrete type Mapping<Int>. Unfortunately, typealias does not appear to support generics at this point, so a struct is probably the best tool we have.

请注意,虽然 typealias 是废话,但显然可以专门化函数变量本身.我知道这不是闭包,但在某些相同的情况下可能很有用.

Note that while typealias is a bust, it is clearly possible to specialize function variables themselves. This isn't a closure, I know, but may be useful in some of the same situations.

func Identity<T>(i:T) -> T {
  return i
}

let identityInt:(Int -> Int) = Identity
identityInt(1) // => 1

用这个来进一步探索抽象类型的问题,考虑:

Using this to explore the problem of abstract types a little more, consider:

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 进行比较,我将其明确指定为具体类型,然后可以构造.

That's because the type (T) -> T is not a concrete type, so you can't have one called x. Compare that to identityInt, which I explicitly specialized into a concrete type, and then could construct.

这篇关于泛型作为快速闭包的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆