Ошибка компилятора функции Swift «отсутствует возврат»

Я пытался заставить эту функцию возвращать значение Bool, но я не понимаю, почему я получаю сообщение об ошибке «отсутствует возврат в функции, которая, как ожидается, вернет« Bool ». Я искал в Интернете и пробовал разные вещи, но я не могу найти решение Любая помощь будет оценена!

func trueSquare(a:[Int], b:[Int]) -> Bool {
    for i in b[0]...b.endIndex {
        if b[i] == a[i]*a[i] {
            return true
        }
        else {
            return false
        }
    }
}

РЕДАКТИРОВАТЬ: я изменил цикл на for i in 0...(b.count - 1), но я все еще получаю ту же ошибку, даже когда я вызываю функцию с a и b, имеющими одинаковое количество элементов.


person Dan Hilton    schedule 23.01.2019    source источник
comment
Вы получаете эту ошибку, потому что что произойдет, если массив b пуст и вы никогда не сможете запустить цикл for? Кроме того, вы пытаетесь проверить, является ли b[i] == a[i]*a[i], но это приведет к сбою, если a имеет меньше элементов, чем b.   -  person emrepun    schedule 23.01.2019
comment
Что, если b.endIndex меньше b[0]?   -  person Travis Griggs    schedule 23.01.2019
comment
Что-то вроде return zip(a, b).contains(where: { $0 * $0 == $1 }) может быть более простым способом получить результат.   -  person Martin R    schedule 23.01.2019
comment
...b.endIndex тоже неверно — endIndex — это индекс «один после конца». Лучше: for i in b.indices { ... }   -  person Martin R    schedule 23.01.2019
comment
Вдобавок ко всему остальному, что было сказано, цикл в любом случае никогда не выходит за пределы первой итерации.   -  person jscs    schedule 23.01.2019
comment
Я вижу, что запутался между индексом и элементом массива. Я пытаюсь выполнить цикл в диапазоне от первого до последнего индекса. Итак, если в массиве 5 значений, я хочу, чтобы он повторялся 5 раз.   -  person Dan Hilton    schedule 23.01.2019
comment
@DanHilton Вы не можете использовать return внутри цикла, если хотите повторить весь цикл.   -  person rmaddy    schedule 24.01.2019


Ответы (3)


Что делать, если в вашем массиве нет элемента? Затем для каждого цикла никогда не выполняется, и тогда ваш метод не возвращает ничего, что явно неверно. Поэтому вам нужно возвращать значение даже вне цикла.


Но у тебя логика плохая. Вы возвращаете логическое значение в зависимости от того, равен ли только первый элемент из b a*a.

Итак, логика должна быть примерно такой: если каждый элемент соответствует условию, то вернуть true, иначе вернуть false. Для этого в Swift 4.2+ вы можете использовать метод allSatisfy

func trueSquare(a:[Int], b:[Int]) -> Bool {
    guard a.count == b.count else { return false } // if arrays have different number of elements, return false
    return a.enumerated().allSatisfy {$0.element * $0.element == b[$0.offset]}
}
person Robert Dresler    schedule 23.01.2019

Я подозреваю, что компилятор требует возвращаемое значение для случая, когда цикл вообще не выполняется.

Теперь ClosedRange никогда не может быть пустым, поэтому b[0]...b.endIndex никогда не будет пустым (если это приведет к пустому или недопустимому диапазону, код выйдет из строя), но компилятор недостаточно умен, чтобы знать это.

PS: Вы уверены, что b[0]...b.endIndex на самом деле является последовательностью, которую вы хотите зациклить? Это создает диапазон от первого элемента b до endIndex b. Это не имеет для меня никакого смысла.

person Ole Begemann    schedule 23.01.2019
comment
Я изменил цикл на "for i in 0...(b.count - 1)" и попытался установить a:[4, 8, 16, 20], b:[16, 64, 122, 200], но все равно получаю ту же ошибку - person Dan Hilton; 23.01.2019

Ваша функция не обрабатывает случай, когда b — пустой массив. Вам нужно определить, каким должно быть возвращаемое значение для такого случая, потому что ваш цикл будет пропущен, когда b является пустым массивом.

Во-вторых, у вас тоже логика неполная, потому что если условие хорошее для i==0, вы сразу возвращаете true, не проверяя остальные пункты.

В-третьих, вы, вероятно, захотите убедиться, что a и b имеют одинаковую длину.

Итак, вот как должна выглядеть ваша функция:

func trueSquare(a:[Int], b:[Int]) -> Bool {
    if a.count != b.count {
        return false
    }
    for i in 0..<b.count {
        if b[i] != a[i]*a[i] {
            return false
        }
    }
    return true
}
person david72    schedule 23.01.2019