Hızlı bir şekilde isteğe bağlı kapatma nasıl yapılır?


93

Swift'de isteğe bağlı olarak kapanış gerektiren bir argüman ilan etmeye çalışıyorum. İlan ettiğim işlev şuna benziyor:

class Promise {

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

}

Ancak Swift, "if let" ifadesinin bildirildiği "bir koşuldaki bağlı değerin İsteğe Bağlı bir tür olması gerektiğinden" şikayet eder.


Parametrelerle yalnızca tek bir kapatma kullanmayı düşünün.
catanore

Yanıtlar:


113

İsteğe bağlı kapanışı parantez içine almalısınız. Bu, ?operatörü uygun şekilde kapsayacaktır .

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

Parantez içine almak zorunda kalmanın mantığının ne olduğunu biliyor musunuz?
Marcosc

5
Muhtemelen belirsizliği ortadan kaldırmak için. İsteğe bağlı kapanış bir dönüş değerine sahip olsaydı, ne ()->Int?anlama geldiği konusunda kafa karıştırıcı olabilirdi .
Cezar

3
Ayrıca, Swift kitabından: “İsteğe bağlı bir tür bildirirken,? Şebeke. Örnek olarak, isteğe bağlı bir tamsayı dizisi bildirmek için, tür ek açıklamasını (Int [])? Olarak yazın; Int [] yazıyor musunuz? bir hata üretir. "
Cezar

@Cezar "İsteğe bağlı kapatma" nın neden ve nerede kullanılacağını biraz açıklar mısınız, bunu merak ediyorum.
iLearner

@Cezar Şu anda Mac'te değil, bu yüzden sözdizimim biraz bozuk olabilir, ancak ?gerçekten sadece şeker olduğunu unutmayın Optional<T>, böylece `func sonra (onFulfilled: () -> (), onReject: İsteğe bağlı <() -> ()>) {`o zaman ()fazlalığa ihtiyacınız olmaz, ancak IMO ()?daha güzeldir. Ayrıca bir tür takma adla daha da güzelleştirebilirsiniz typealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
Andrew Carter

63

Kodu daha da kısaltmak niliçin onRejectparametre için varsayılan değer olarak ve ?()onu çağırırken isteğe bağlı zincirleme olarak kullanabiliriz:

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

Bu şekilde işlevi onRejectçağırdığımızda parametreyi atlayabiliriz then.

then({ /* on fulfilled */ })

onRejectParametreyi thenişleve geçirmek için sondaki kapanış sözdizimini de kullanabiliriz :

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

İşte bununla ilgili bir blog yazısı .


34

Bu "isteğe bağlı" kapatmanın hiçbir şey yapmaması gerektiğini varsaydığım için, varsayılan değer olarak boş bir kapanışa sahip bir parametre kullanabilirsiniz:

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

bu işlev artık onRejectgeri arama ile veya geri arama olmadan çağrılabilir

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

Swift'in harika olmasına gerek yok Optionals?!


Bu güzel bir çözüm!
Roland T.

6

Belki daha temiz bir yoldur. Özellikle kapanış karmaşık parametrelere sahip olduğunda.

typealias SimpleCallBack = () -> ()

class Promise {

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.