Wiązanie warunkowe: jeśli let błąd - inicjator dla powiązania warunkowego musi mieć typ opcjonalny

120

Próbuję usunąć wiersz z mojego źródła danych i następujący wiersz kodu:

if let tv = tableView {

powoduje następujący błąd:

Inicjator dla powiązania warunkowego musi mieć typ opcjonalny, a nie UITableView

Oto pełny kod:

// 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)

Jak mam poprawić poniższe?

 if let tv = tableView {
Del Hinds
źródło
8
ponieważ tableViewnie jest wartością opcjonalną, nie ma potrzeby sprawdzania, czy jest zerowa, czy nie. Więc możesz go bezpośrednio użyć, mam na myśli usunięcie tego if let i po prostu użyj tableVieww funkcji
Eric Qian
Dla potomnych, po naprawieniu tego problemu, natknąłem się na ten problem, variable with getter/setter cannot have an initial valuektóry został rozwiązany po prostu przez usunięcie pozostałego bloku {} po inicjalizacji, ala ta odpowiedź: stackoverflow.com/a/36002958/4544328
Jake T.

Odpowiedzi:

216

if let/ if varopcjonalne wiązanie działa tylko wtedy, gdy wynik prawej strony wyrażenia jest opcjonalny. Jeśli wynik po prawej stronie nie jest opcjonalny, nie możesz użyć tego opcjonalnego wiązania. Celem tego opcjonalnego powiązania jest sprawdzenie nili użycie zmiennej tylko wtedy, gdy nie jest nil.

W twoim przypadku tableViewparametr jest zadeklarowany jako typ nieopcjonalny UITableView. Gwarantujemy, że nigdy nie będzie nil. Więc opcjonalne wiązanie tutaj jest niepotrzebne.

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)

Wszystko, co musimy zrobić, to pozbyć się tego if leti zmienić wszelkie występujące tvw nim wystąpienia na sprawiedliwe tableView.

nhgrif
źródło
17

dla mojego konkretnego problemu musiałem wymienić

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

Z

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
źródło
2
Najlepsza odpowiedź tego gościa zobacz komentarze stackoverflow.com/a/31039427/2797944
Shauket Sheikh
16

W przypadku korzystania z niestandardowego typu komórki, na przykład ArticleCell, możesz otrzymać komunikat o błędzie:

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

Otrzymasz ten błąd, jeśli linia kodu wygląda mniej więcej tak:

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

Możesz naprawić ten błąd, wykonując następujące czynności:

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

Jeśli zaznaczysz powyższe, zobaczysz, że ta ostatnia używa opcjonalnego rzutowania dla komórki typu ArticleCell.

Lehlohonolo_Isaac
źródło
W moim przypadku potrzebowałem użyćas! ArticleCell?
lilbiscuit
9

To samo dotyczy instrukcji strażnika . Ten sam komunikat o błędzie prowadzi mnie do tego postu i odpowiedzi (dzięki @nhgrif).

Kod: Drukuj nazwisko osoby tylko wtedy, gdy drugie imię ma mniej niż cztery znaki.

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)!")
}

Dopóki nie zadeklarowałem ostatniego jako parametru opcjonalnego, widziałem ten sam błąd.

Paul Tader
źródło
4

powiązanie warunku musi mieć typ opcjonalny, co oznacza, że ​​można wiązać tylko wartości opcjonalne w instrukcji 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? {


        }
    }
}

To zadziała dobrze, ale upewnij się, że jeśli używasz, jeśli pozwolisz, musi mieć typ opcjonalny „?”

Viral Shah
źródło
0

Cóż, nadal byłoby wygodne (składniowo), gdybyśmy mogli zadeklarować zwykłe wartości wewnątrz warunku if. Oto sztuczka: możesz sprawić, by kompilator pomyślał, że istnieje przypisanie Optional.some(T)do wartości w następujący sposób:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
Artem Ilyumzhinov
źródło