web-dev-qa-db-fra.com

Impossible de trouver une surcharge pour '/' qui accepte les arguments fournis

// Playground - noun: a place where people can play


func getAverage(numbers: Int...) -> Double{
    var total = 0
    var average:Double = 0

    for number in numbers{
        total = total + number
    }

    average = total / numbers.count

    return average
}

getAverage(3, 6)

Je reçois une erreur sur average = total / numbers.count

Impossible de trouver une surcharge pour '/' qui accepte les arguments fournis

J'ai essayé de réparer en faisant:

average = Double(total/numbers.count)

mais le getAverage a été défini sur 4 au lieu de 4.5

36
Arian Faurtosh

Il n'y a pas de telles conversions implicites dans Swift, vous devrez donc les convertir explicitement vous-même:

average = Double(total) / Double(numbers.count)

De ( Le Swift : " Les valeurs ne sont jamais implicitement converties en un autre type. "(Section: A Swift Tour)

Mais vous utilisez maintenant Swift, pas Objective-C, alors essayez de penser de manière plus fonctionnelle. Votre fonction peut être écrite comme ceci:

func getAverage(numbers: Int...) -> Double {
    let total = numbers.reduce(0, combine: {$0 + $1})
    return Double(total) / Double(numbers.count)
}

reduce prend un premier paramètre comme valeur initiale pour une variable d'accumulateur, puis applique la fonction combine à la variable d'accumulateur et à chaque élément du tableau. Ici, nous transmettons une fonction anonyme qui utilise $0 Et $1 Pour désigner les premier et deuxième paramètres qui lui sont transmis et les additionne.

Encore plus concis, vous pouvez écrire ceci: numbers.reduce(0, +).

Notez comment l'inférence de type fait un travail agréable de toujours découvrir que total est un Int.

62

Le compilateur sélectionne une implémentation de l'opérateur / En fonction de vos paramètres d'entrée et de sortie. Dans votre cas, les paramètres d'entrée sont deux valeurs Int et le paramètre de sortie est Double. C'est ce que le compilateur recherche:

func / (left: Int, right: Int) -> Double

Cependant, il n'y a pas une telle implémentation de l'opérateur /, C'est pourquoi vous obtenez l'erreur. Lorsque vous effectuez Double(total/numbers.count), votre paramètre de sortie devient Int, c'est pourquoi le compilateur choisit l'implémentation suivante pour l'opérateur / Qui existe:

func / (left: Int, right: Int) -> Int

C'est pourquoi vous obtenez 4 Au lieu de 4.5, Même si vous convertissez le résultat en Double par la suite.

Vous pouvez fournir votre propre implémentation de l'opérateur / Qui convertit d'abord vos nombres en Doubles:

func / (left: Int, right: Int) -> Double {
    return Double(left) / Double(right)
}

Ensuite, vous pouvez effectuer les opérations suivantes:

let a: Int = 3
let b: Int = 2
let c: Double = a/b  // -> 1.5
6
Tom