Подтвердить что ты не робот

Не удается расширить закрытие в Swift?

С волнением от расширения 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.

4b9b3361

Ответ 1

Что такое не номинальный тип?

A номинальный тип - это тип с явным именем. Не номинальный тип - это тип без такого имени, например () -> (). Составные типы, включая замыкания и кортежи (например, (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