2015-06-18 1 views
10

Флеш с волнением от расширения Bool, я думал, что было бы интересно продлить закрытие в Swift (мы сделали это без суеты вообще в Smalltalk, так почему бы и нет?).Не удается расширить закрытие в Swift?

Вот моя площадка:

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

Вы не можете продлить закрытия. Сравните http://stackoverflow.com/questions/28317625/can-i-extend-tuples-in-swift (что касается расширения кортежей, но тот же ответ применяется к функциям/закрытию). –

+0

Любая идея _WHY_ кортежей и закрытий не расширяется? В случае замыкания, является ли это потому, что закрытие никогда не реально подтверждается фактическим объектом (или структурой)? (по крайней мере, я не вижу нигде, где они это делают) –

+1

@TravisGriggs Это «[в основном ограничение реализации] (https://twitter.com/jckarter/status/611656674391097344)». –

ответ

8

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

A 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 
+0

«Вы можете использовать композицию вместо расширений, возможно, используя новые функции протокола Swift 2». Я не уверен, как это сработает. Я мог бы сделать протокол 'AnswersTheBigQuestion', но я не смог бы продлить« не номинальный »тип, чтобы принять этот протокол, не так ли? Поскольку вы, видимо, не можете их продлить. –

+0

@TravisGriggs Я просто добавил пример. Вы можете создать структуру, которая * имеет * NiladicClosure', вместо того, чтобы делать что-то, что * является * NiladicClosure'. –

Смежные вопросы