2
votes

Erreur du compilateur de fonction Swift 'retour manquant'

J'ai essayé de faire en sorte que cette fonction renvoie une valeur booléenne mais je ne comprends pas pourquoi j'obtiens l'erreur "retour manquant dans une fonction qui devrait renvoyer" Bool ". J'ai cherché en ligne et j'ai essayé différentes choses mais je n'arrive pas à trouver une solution. Toute aide serait appréciée!

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
        }
    }
}

EDIT: J'ai changé la boucle en pour i en 0 ... (b.count - 1) mais j'obtiens toujours la même erreur même lorsque j'appelle la fonction avec a et b ayant tous les deux le même nombre d'éléments.


7 commentaires

Vous obtenez cette erreur car que se passe-t-il si le tableau b est vide et que vous ne pouvez jamais exécuter pour la boucle? Aussi, vous essayez de vérifier si b [i] == a [i] * a [i] mais cela plantera si a a moins d'éléments que b.


Et si b.endIndex était inférieur à b [0] ?


Quelque chose comme return zip (a, b) .contains (où: {$ 0 * $ 0 == $ 1}) pourrait être un moyen plus simple d'obtenir le résultat.


... b.endIndex est également faux - endIndex est l'index «un après la fin». Mieux: for i dans b.indices {...}


En plus de tout ce qui a été dit, la boucle ne dépasse de toute façon jamais la première itération.


Je vois que je suis devenu confus entre l'index et l'élément du tableau. J'essaie d'exécuter la boucle dans la plage du premier index au dernier index. Donc, s'il y a 5 valeurs dans le tableau, je veux qu'il boucle 5 fois


@DanHilton Vous ne pouvez pas utiliser return dans la boucle si vous souhaitez itérer toute la boucle.


3 Réponses :


2
votes

Je soupçonne que le compilateur a besoin d'une valeur de retour pour le cas où la boucle n'est pas exécutée du tout.

Désormais, un ClosedRange ne peut jamais être vide, donc b [0] ... b.endIndex ne sera jamais vide (s'il en résulte ou plage invalide, le code planterait), mais le compilateur n'est pas assez intelligent pour le savoir.

PS: Etes-vous sûr que b [0] ... b.endIndex est réellement la séquence sur laquelle vous voulez boucler. Cela crée une plage entre le premier élément de b et le endIndex de b . Cela n'a aucun sens pour moi.


1 commentaires

J'ai changé la boucle en 'for i in 0 ... (b.count - 1)' et j'ai essayé de définir a: [4, 8, 16, 20], b: [16, 64, 122, 200] mais toujours la même erreur



1
votes

Votre fonction ne gère pas le cas où b est un tableau vide. Vous devez définir ce que vous voulez que la valeur de retour soit dans ce cas, car votre boucle sera ignorée lorsque b est un tableau vide.

Deuxièmement, votre logique est également incomplète, car si la condition est bonne pour i == 0, vous retournez immédiatement true, sans vérifier le reste des éléments.

Troisièmement, vous voulez probablement vous assurer que a et b ont la même longueur.

Voici donc votre fonction devrait ressembler à:

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
}


0 commentaires

3
votes

Et si votre tableau ne contient aucun élément? Ensuite, pour chaque boucle ne s'exécute jamais et votre méthode ne renvoie rien de ce qui est évidemment faux. Vous devez donc renvoyer une valeur même en dehors de la boucle.


Mais votre logique est mauvaise. Vous renvoyez une valeur booléenne selon que le premier élément de b est égal à a * a .

Donc, la logique devrait être quelque chose comme: si chaque élément remplit la condition, alors renvoie true , sinon, retourne false . Pour ce faire, dans Swift 4.2+, vous pouvez utiliser la méthode 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]}
}


0 commentaires