2015-06-18 16 views
10

Flush z ekscytacją z rozszerzenia Bool, Myślałem, że byłoby fajnie rozszerzyć zamknięcia w Swift (zrobiliśmy to bez żadnego zamieszania w Smalltalk, więc dlaczego nie?).Nie można przedłużyć zamknięcia w Swift?

Oto mój zabaw:

typealias NiladicClosure =() ->() 

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

let block:NiladicClosure = {} 

block.theAnswerToLife 

To nie działa, mówiąc, że NiladicClosure does not have a member named 'theAnswerToLife'. Patrząc w konsolę, otrzymuję nieco więcej informacji:

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

Co to jest non-nominal type? Czy istnieje wzór/obejście?

Inne podobne pytania sprzed Swift 2, również były na tyle konkretne, że ludzie oferowali obejście określonego rozszerzenia. Interesuje mnie, czy zamknięcia Swift są obiektami pierwszej klasy, do których mogę dodać dodatkowe zachowanie, jak inne rzeczy w Swift.

+1

Nie można rozszerzyć zamknięć. Porównaj http://stackoverflow.com/questions/28317625/can-i-extend-tuples-in-swift (co dotyczy rozszerzenia krotek, ale ta sama odpowiedź dotyczy funkcji/zamknięć). –

+0

Każda idea _WHY_ krotek i zamknięć nie jest rozszerzalna? W przypadku zamknięcia, czy to dlatego, że zamknięcia nigdy nie są reifikowane rzeczywistym obiektem (lub strukturą)? (przynajmniej nigdzie nie widzę, gdzie to robią) –

+1

@TravisGriggs To jest "[głównie ograniczenie implementacji] (https://twitter.com/jckarter/status/611656674391097344)". –

Odpowiedz

8

Co to jest typ nie-nominalny?

A nominal type to typ o jawnej nazwie. Typ nienamalny to typ bez takiej nazwy, na przykład () ->(). Nie można rozszerzyć typów związków, w tym zamknięć i krotek (takich jak (Int, String)).

Czy istnieje wzór/obejście?

zamiast Można użyć kompozycję rozszerzeń, być może przy użyciu nowych funkcji protokołu Swift 2 za:

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

"Można użyć kompozycji zamiast rozszerzeń, być może używając nowych funkcji protokołu Swift 2". Nie jestem pewien, jak to by działało. Mógłbym stworzyć protokół 'AnswersTheBigQuestion', ale nie byłbym w stanie rozszerzyć typu' nie nominalnego', aby przyjąć ten protokół, czyż nie? Ponieważ najwyraźniej nie możesz ich przedłużyć. –

+0

@TravisGriggs Właśnie dodałem przykład. Możesz stworzyć strukturę, która * ma * "NiladicClosure", zamiast tworzyć coś, co * jest * 'NiladicClosure'. –

Powiązane problemy