【问题标题】:Can't extend closure in Swift?不能在 Swift 中扩展闭包?
【发布时间】:2015-06-18 21:34:07
【问题描述】:

扩展 Bool 让我兴奋不已,我认为在 Swift 中扩展闭包会很有趣(我们在 Smalltalk 中完全没有大惊小怪,为什么不呢?)。

这是我的游乐场:

typealias NiladicClosure = () -> ()

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

let block:NiladicClosure = {}

block.theAnswerToLife

不行,说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 {
^         ~~~~~~~~~~~~~~

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

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

【问题讨论】:

  • 你不能扩展闭包。比较stackoverflow.com/questions/28317625/…(这是关于扩展元组,但同样的答案适用于函数/闭包)。
  • 知道 WHY 元组和闭包不可扩展吗?在闭包的情况下,是因为闭包实际上从未用实际对象(或结构)具体化吗? (至少,我看不到他们在哪里)
  • @TravisGriggs 这是“mostly an implementation limitation”。

标签: swift closures swift2


【解决方案1】:

什么是非标称类型?

nominal type 是具有明确名称的类型。非名义类型是没有这样名称的类型,例如() -> ()。不能扩展复合类型,包括闭包和元组(例如 (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

【讨论】:

  • “你可以使用组合而不是扩展,也许使用 Swift 2 的新协议特性。”我不确定那将如何工作。我可以制定一个AnswersTheBigQuestion 协议,但我不能扩展non-nominal 类型以采用该协议,对吗?因为您显然无法扩展它们。
  • @TravisGriggs 我刚刚添加了一个示例。您可以创建一个 具有 NiladicClosure 的结构,而不是创建 NiladicClosure 的结构。
猜你喜欢
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 2015-02-04
  • 2011-11-13
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多