Условное связывание: if let error - Инициализатор для условного связывания должен иметь необязательный тип

120

Я пытаюсь удалить строку из своего источника данных и следующую строку кода:

if let tv = tableView {

вызывает следующую ошибку:

Инициализатор для условной привязки должен иметь тип Optional, а не UITableView.

Вот полный код:

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

Как мне исправить следующее?

 if let tv = tableView {
Дель Хиндс
источник
8
поскольку tableViewне является необязательным значением, нет необходимости проверять, равно ли оно нулю. Таким образом, вы можете напрямую использовать его, я имею в виду удалить это if let и просто использовать tableViewв функции
Эрик Цянь
Для потомков, после того как я исправил эту проблему, я столкнулся с ней variable with getter/setter cannot have an initial value, которая была решена путем простого удаления оставшегося блока {} после инициализации, как этот ответ: stackoverflow.com/a/36002958/4544328
Джейк Т.

Ответы:

216

if letif varСвязывание / optional работает, только если результат правой части выражения является необязательным. Если результат правой стороны не является необязательным, вы не можете использовать эту необязательную привязку. Смысл этой необязательной привязки - проверять nilи использовать переменную только в том случае, если она не является nil.

В вашем случае tableViewпараметр объявлен как необязательный тип UITableView. Гарантированно, что никогда не будет nil. Так что необязательная привязка здесь не нужна.

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)

Все, что нам нужно сделать, это избавиться от if letи заменить все вхождения tvвнутри него на just tableView.

nhgrif
источник
17

для моей конкретной проблемы мне пришлось заменить

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

С участием

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
источник
2
Лучший ответ этого парня см. В комментариях stackoverflow.com/a/31039427/2797944
Shauket Sheikh
16

В случае, если вы используете настраиваемый тип ячейки, скажем ArticleCell, вы можете получить сообщение об ошибке:

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

Вы получите эту ошибку, если ваша строка кода будет выглядеть примерно так:

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

Вы можете исправить эту ошибку, выполнив следующие действия:

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

Если вы проверите указанное выше, вы увидите, что последний использует необязательное приведение типов для ячейки типа ArticleCell.

Lehlohonolo_Isaac
источник
В моем случае мне нужно было использоватьas! ArticleCell?
lilbiscuit
9

То же самое касается заявлений охранников . То же сообщение об ошибке привело меня к этому сообщению и ответу (спасибо @nhgrif).

Код: печатайте фамилию человека, только если отчество меньше четырех символов.

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

Пока я не объявил последний в качестве необязательного параметра, я видел ту же ошибку.

Пол Тейдер
источник
4

привязка условия должна иметь оптический тип, что означает, что вы можете связывать только необязательные значения в инструкции 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? {


        }
    }
}

Это будет работать нормально, но убедитесь, что при использовании if let он должен иметь оптический тип "?"

Виральный Шах
источник
0

Что ж, все равно было бы удобно (синтаксически), если бы мы могли объявить обычные значения внутри условия if. Итак, вот трюк: вы можете заставить компилятор думать, что существует присвоение Optional.some(T)значения следующему:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
Артем Илюмжинов
источник