无法在Swift中扩展闭包?

Tra*_*ggs 10 closures swift swift2

从扩展中Bool感到兴奋,我认为在Swift中扩展闭包会很有趣(我们在Smalltalk中完全没有大惊小怪,所以为什么不呢?).

这是我的游乐场:

typealias NiladicClosure = () -> ()

extension NiladicClosure {
    var theAnswerToLife:Int {
        return 42
    }
}

let block:NiladicClosure = {}

block.theAnswerToLife
Run Code Online (Sandbox Code Playgroud)

这说不起作用NiladicClosure does not have a member named 'theAnswerToLife'.在控制台中查看,我获得了更多信息:

Playground execution failed: /var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/33726/playground119.swift:3:1: error: non-nominal type 'NiladicClosure' cannot be extended
extension NiladicClosure {
^         ~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

什么是non-nominal type?有模式/解决方法吗?

其他类似的问题早于Swift 2,也足够具体,人们为特定的扩展提供了变通方法.我对Swift闭包是否是可以添加其他行为的第一类对象感兴趣,就像Swift中的其他东西一样.

Aar*_*ger 8

什么是非名义类型?

一个名义类型是带有明确名称的类型.非名义类型是没有这样名称的类型,例如() -> ().复合类型,包括闭包和元组(如(Int, String))不能扩展.

有模式/解决方法吗?

您可以使用组合而不是扩展,也许使用Swift 2的新协议功能:

typealias NiladicClosure = () -> ()

protocol NiladicClosureProtocol {
    var someClosure : NiladicClosure? {get}
}

protocol SorryForTheInconvenience {
    var theAnswerToLife : Int {get}
}

extension SorryForTheInconvenience {
    var theAnswerToLife : Int {
        return 42
    }
}

struct SomethingAwesome : NiladicClosureProtocol, SorryForTheInconvenience {
    var someClosure : NiladicClosure?
}

let foo = SomethingAwesome()
foo.theAnswerToLife // 42
Run Code Online (Sandbox Code Playgroud)