// 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
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
.
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 Double
s:
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