Не удается расширить закрытие в 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.
Ответы
Ответ 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