Грешка на компилатора на 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
Промених цикъла на „за i в 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