Conditional Binding: if let error - Penginisialisasi untuk pengikatan bersyarat harus memiliki tipe Opsional

120

Saya mencoba menghapus baris dari Sumber Data saya dan baris kode berikut:

if let tv = tableView {

menyebabkan kesalahan berikut:

Penginisialisasi untuk pengikatan bersyarat harus memiliki tipe Opsional, bukan UITableView

Ini kode lengkapnya:

// Override to support editing the table view.
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        // Delete the row from the data source

    if let tv = tableView {

            myData.removeAtIndex(indexPath.row)

            tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

Bagaimana saya harus memperbaiki yang berikut ini?

 if let tv = tableView {
Del Hinds
sumber
8
karena tableViewbukan nilai opsional, tidak perlu memeriksa apakah nilainya nihil atau tidak. Jadi Anda bisa langsung menggunakannya, maksud saya hapus itu if let dan cukup gunakan tableViewdalam fungsinya
Eric Qian
Untuk anak cucu, setelah saya memperbaiki masalah ini, saya mengalami variable with getter/setter cannot have an initial value, yang diselesaikan hanya dengan menghapus blok {} sisa setelah inisialisasi, melalui jawaban ini: stackoverflow.com/a/36002958/4544328
Jake T.

Jawaban:

216

if let/ if varpenjilidan opsional hanya berfungsi jika hasil dari sisi kanan ekspresi adalah opsional. Jika hasil dari sisi kanan bukan merupakan opsional, Anda tidak dapat menggunakan penjilidan opsional ini. Inti dari pengikatan opsional ini adalah untuk memeriksa nildan hanya menggunakan variabel jika bukan- nil.

Dalam kasus Anda, tableViewparameter dideklarasikan sebagai tipe non-opsional UITableView. Dijamin tidak akan pernah nil. Jadi pengikatan opsional di sini tidak diperlukan.

func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        myData.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

Yang harus kita lakukan adalah menyingkirkan if letdan mengubah kejadian apa pun tvdi dalamnya menjadi adil tableView.

nhgrif
sumber
17

untuk masalah khusus saya, saya harus mengganti

if let count = 1
    {
        // do something ...
    }

Dengan

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
sumber
2
Jawaban terbaik oleh orang ini lihat komentar stackoverflow.com/a/31039427/2797944
Shauket Sheikh
16

Dalam kasus di mana Anda menggunakan tipe sel kustom, misalnya ArticleCell, Anda mungkin mendapatkan kesalahan yang mengatakan:

    Initializer for conditional binding must have Optional type, not 'ArticleCell'

Anda akan mendapatkan kesalahan ini jika baris kode Anda terlihat seperti ini:

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as! ArticleCell 

Anda dapat memperbaiki kesalahan ini dengan melakukan hal berikut:

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as ArticleCell?

Jika Anda memeriksa hal di atas, Anda akan melihat bahwa yang terakhir menggunakan casting opsional untuk sel tipe ArticleCell.

Lehlohonolo_Isaac
sumber
Dalam kasus saya, saya perlu menggunakanas! ArticleCell?
lilbiscuit
9

Hal yang sama berlaku untuk pernyataan penjaga . Pesan kesalahan yang sama membawa saya ke posting dan jawaban ini (terima kasih @nhgrif).

Kode: Cetak nama belakang orang tersebut hanya jika nama tengahnya kurang dari empat karakter.

func greetByMiddleName(name: (first: String, middle: String?, last: String?)) {
    guard let Name = name.last where name.middle?.characters.count < 4 else {
        print("Hi there)")
        return
    }
    print("Hey \(Name)!")
}

Sampai saya menyatakan terakhir sebagai parameter opsional, saya melihat kesalahan yang sama.

Paul Tader
sumber
4

pengikatan kondisi harus memiliki tipe optinal yang berarti bahwa Anda hanya dapat mengikat nilai opsional dalam pernyataan if let

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

        // Delete the row from the data source

        if let tv = tableView as UITableView? {


        }
    }
}

Ini akan bekerja dengan baik tetapi pastikan ketika Anda menggunakan jika membiarkannya harus memiliki tipe optinal "?"

Viral Shah
sumber
0

Yah, akan tetap nyaman (secara sintaksis) jika kita bisa mendeklarasikan nilai biasa di dalam kondisi if. Jadi, inilah triknya: Anda dapat membuat kompiler berpikir ada penugasan Optional.some(T)ke nilai seperti ini:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
Artem Ilyumzhinov
sumber