我将以下函数编写为闭包时遇到问题
func myfunc<S where S: MyProtocol, S: MySuperClass>(param: S) { ... }
Run Code Online (Sandbox Code Playgroud)
我试过了
let myClosure = {<S where S: MyProtocol, S: MySuperClass>(param: S) in ... }
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
有什么建议?
Rob*_*ier 17
我相信你要求的东西没有意义(与Swift无关).虽然我有兴趣被证明是错误的,但我不认为这可以用任何强类型语言合理地创建.(编辑:继续我的研究,我相信这可能是一种具有一流多态性的语言,但我不知道任何实际具有此功能的通用语言.)
let myClosure = {<S where S: MyProtocol, S: MySuperClass>(param: S) in ... }
Run Code Online (Sandbox Code Playgroud)
你期望什么类型myClosure?泛型创建抽象类型.在专业化之前它不会成为真正的类型.那myClosure将是一个抽象类型本身.这就像要求一个抽象类的实例."抽象"的全部意义在于你无法构建一个.你可以说最好的是它myClosure本身就是你需要实例化到一个真实实例中的类型(但是let没有任何意义;你没有let类型).
当你将它包装成a时struct,你真正在做的是创建一个抽象类型,在创建实例时,你将专门化为真实类型.
现在有意义的IMO(但目前似乎不可能),是这样的:
typealias Mapping<S> = S -> S
let identity: Mapping<Int> = { return $0 }
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为你定义了一个抽象类型(Mapping),然后实例化一个具体的类型Mapping<Int>.不幸的是,此时typealias似乎不支持泛型,因此struct可能是我们拥有的最佳工具.
请注意,虽然typealias是一个半身像,但很明显可以自己专门化函数变量.我知道,这不是一个闭包,但在某些相同的情况下可能会有用.
func Identity<T>(i:T) -> T {
return i
}
let identityInt:(Int -> Int) = Identity
identityInt(1) // => 1
Run Code Online (Sandbox Code Playgroud)
使用它来更多地探讨抽象类型的问题,请考虑:
func Identity<T>(i:T) -> T { return i }
let x = Identity
Run Code Online (Sandbox Code Playgroud)
这无法编译错误:
error: cannot convert the expression's type '(T) -> T' to type '(T) -> T'
Run Code Online (Sandbox Code Playgroud)
那是因为类型(T) -> T不是具体类型,所以你不能有一个被调用的类型x.将其与identityInt我明确专门化为具体类型的内容进行比较,然后进行构造.
您可以尝试将闭包包装在声明泛型类型的结构中。就像是:
struct ClosureWrapper<S where S: MyClass, S: MyProtocol> {
let myClosure = {(param: S) in ... }
}
Run Code Online (Sandbox Code Playgroud)
当然,此时你的闭包也可能是一个正常的函数:P
| 归档时间: |
|
| 查看次数: |
8017 次 |
| 最近记录: |