Bagaimana seseorang membuat penutupan opsional dengan cepat?


93

Saya mencoba menyatakan argumen di Swift yang membutuhkan penutupan opsional. Fungsi yang telah saya nyatakan terlihat seperti ini:

class Promise {

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

}

Namun Swift mengeluh bahwa "Nilai terikat dalam kondisional harus berupa tipe Opsional" di mana "jika biarkan" dideklarasikan.


Pertimbangkan untuk menggunakan hanya satu penutupan dengan parameter.
catanore

Jawaban:


113

Anda harus memasukkan penutup opsional dalam tanda kurung. Ini akan mencakup ?operator dengan benar.

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

Tahukah Anda apa alasan mengapa harus menyertakannya dalam tanda kurung?
Marcosc

5
Mungkin untuk menghilangkan ambiguitas. Jika penutupan opsional memiliki nilai kembali, itu bisa membingungkan untuk apa ()->Int?artinya.
Cezar

3
Selain itu, dari buku Swift: “Saat mendeklarasikan tipe opsional, pastikan untuk menggunakan tanda kurung untuk mencakup? operator. Sebagai contoh, untuk mendeklarasikan larik bilangan bulat opsional, tulis anotasi tipe sebagai (Int []) ?; menulis Int []? menghasilkan kesalahan. "
Cezar

@Cezar Bisakah Anda menjelaskan sedikit mengapa dan di mana menggunakan "Penutupan opsional", saya penasaran untuk mengetahui ini.
iLearner

@Cezar Tidak ada di mac saat ini jadi sintaks saya mungkin sedikit mati, tapi ingat ?ini sebenarnya hanya gula untuk Optional<T>, jadi Anda juga bisa menulis `func then (onFulfilled: () -> (), onReject: Opsional <() -> ()>) {`maka Anda tidak akan membutuhkan ekstra (), meskipun IMO ()?lebih cantik. Anda juga dapat membuatnya lebih cantik dengan typealias seperti typealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
Andrew Carter

62

Untuk membuat kode lebih pendek, kita dapat menggunakan nilnilai default untuk onRejectparameter dan rangkaian opsional ?()saat memanggilnya:

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

Dengan cara ini kita bisa menghilangkan onRejectparameter saat kita memanggil thenfungsi.

then({ /* on fulfilled */ })

Kita juga bisa menggunakan sintaks penutupan jejak untuk melewatkan onRejectparameter ke dalam thenfungsi:

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

Berikut adalah posting blog tentang itu.


34

Karena saya berasumsi, bahwa penutupan "opsional" ini seharusnya tidak melakukan apa-apa, Anda dapat menggunakan parameter dengan penutupan kosong sebagai nilai default:

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

fungsi ini sekarang dapat dipanggil dengan atau tanpa onRejectcallback

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

Tidak perlu Swift keren di Optionals?sini!


Ini solusi yang bagus!
Roland T.

6

Mungkin ini cara yang lebih bersih. Khususnya jika closure memiliki parameter yang rumit.

typealias SimpleCallBack = () -> ()

class Promise {

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

}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.