Wie macht man schnell einen optionalen Verschluss?


93

Ich versuche, in Swift ein Argument zu deklarieren, das optional geschlossen werden kann. Die von mir deklarierte Funktion sieht folgendermaßen aus:

class Promise {

 func then(onFulfilled: ()->(), onReject: ()->()?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

}

Swift beschwert sich jedoch darüber, dass "Gebundener Wert in einer Bedingung ein optionaler Typ sein muss", in dem "if let" deklariert ist.


Verwenden Sie nur einen Abschluss mit Parametern.
— Catanore

Antworten:


113

Sie sollten den optionalen Verschluss in Klammern setzen. Dadurch wird der ?Bediener ordnungsgemäß erfasst .

func then(onFulfilled: ()->(), onReject: (()->())?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

Wissen Sie, warum Sie es in Klammern setzen müssen?
— Marcosc

5
Wahrscheinlich, um Mehrdeutigkeiten zu beseitigen. Wenn der optionale Abschluss einen Rückgabewert haben sollte, könnte es verwirrend werden, was ()->Int?bedeutet.
— Cezar

3
Außerdem aus dem Swift-Buch: „Wenn Sie einen optionalen Typ deklarieren, müssen Sie Klammern verwenden, um das? Operator. Um beispielsweise ein optionales Array von Ganzzahlen zu deklarieren, schreiben Sie die Typanmerkung als (Int [])?; Int [] schreiben? erzeugt einen Fehler. "
— Cezar

@ Cezar Könnten Sie bitte ein wenig erklären, warum und wo "Optionaler Verschluss" verwendet werden soll? Ich bin gespannt darauf.
— iLearner

@Cezar Im Moment nicht auf einem Mac, daher ist meine Syntax möglicherweise etwas falsch, aber denken Sie daran, dass dies ?wirklich nur Zucker Optional<T>ist. Sie können also auch `func then (onFulfilled: () -> (), onReject: Optional <() schreiben. -> ()>) {`dann würden Sie das Extra nicht brauchen (), obwohl IMO das ()?schöner ist. Sie können es auch mit einem Typealias wietypealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
— Andrew Carter

62

Um den Code noch kürzer zu machen, können wir ihn beim Aufrufen nilals Standardwert für onRejectParameter und optionale Verkettung verwenden ?():

func then(onFulfilled: ()->(), onReject: (()->())? = nil) {
  onReject?()
}

Auf diese Weise können wir onRejectParameter weglassen , wenn wir thenfunction aufrufen .

then({ /* on fulfilled */ })

Wir können auch die Trailing-Closure-Syntax verwenden, um onRejectParameter an die thenFunktion zu übergeben:

then({ /* on fulfilled */ }) {
  // ... on reject
}

Hier ist ein Blog-Beitrag darüber.


34

Da ich davon ausgehe, dass dieser "optionale" Abschluss einfach nichts bewirken sollte, können Sie einen Parameter mit einem leeren Abschluss als Standardwert verwenden:

func then(onFulfilled: ()->(), onReject: ()->() = {}){       
    // now you can call your closures
    onFulfilled()
    onReject()
}

Diese Funktion kann jetzt mit oder ohne onRejectRückruf aufgerufen werden

then({ ... })
then({ ... }, onReject: { ... })

Swift ist Optionals?hier nicht nötig !


Das ist eine schöne Lösung!
— Roland T.

6

Vielleicht ist es ein sauberer Weg. Besonders wenn der Verschluss komplizierte Parameter hat.

typealias SimpleCallBack = () -> ()

class Promise {

func then(onFulfilled: SimpleCallBack, onReject: SimpleCallBack?){       
    if let callableRjector = onReject {
        // do stuff! 
    }
}

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.