En Swift, on peut définir plusieurs fonctions portant le même nom tant que leurs signatures diffèrent. Cette pratique s'appelle la surcharge de fonctions.
Prenons la fonction de base suivante :
func add(_ x: Int, and y: Int, doubleResult: Bool) -> Int {
let sum = x + y
return doubleResult ? sum * 2 : sum
}
let twentySix = add(6, and: 7, doubleResult: true)
// => 26
En Swift, deux fonctions portant le même nom sont considérées comme distinctes si l'une des conditions suivantes est remplie :
Étant donné la fonction add d'origine ci-dessus, chacune des surcharges suivantes est distincte et valide dans le même programme :
// 1. Different number of parameters
func add(_ x: Int, and y: Int) -> Int {
x + y
}
let eleven = add(5, and: 6)
// => 11
// 2. Different parameter type (Double instead of Int)
func add(_ x: Double, and y: Int, doubleResult: Bool) -> Double {
let sum = x + Double(y)
return doubleResult ? sum * 2 : sum
}
let twentySeven = add(6.5, and: 7, doubleResult: true)
// => 27.0
// 3. Different argument label (doubleThat instead of doubleResult)
func add(_ x: Int, and y: Int, doubleThat: Bool) -> Int {
let sum = x + y
return doubleThat ? sum * 2 : sum
}
let thirteen = add(6, and: 7, doubleThat: false)
// => 13
On peut aussi surcharger des fonctions uniquement par leur type de retour. Toutefois, lors de l'appel d'une telle fonction, il faut fournir une annotation de type ou un contexte pour que le compilateur sache quelle surcharge utiliser :
func add(_ x: Int, and y: Int, doubleResult: Bool) -> Double {
let sum = Double(x + y)
return doubleResult ? sum * 2 : sum
}
// Ambiguous call (compiler cannot decide whether you want Int or Double):
// let thirty = add(6, and: 9, doubleResult: true)
// Resolved with an explicit type annotation:
let thirty: Double = add(6, and: 9, doubleResult: true)
// => 30.0
Changer uniquement le nom d'un paramètre interne, sans modifier l'étiquette d'argument, le type de paramètre ou le nombre de paramètres, ne crée pas une fonction distincte. Le compilateur considère cela comme une déclaration dupliquée invalide :
func add(_ w: Int, and y: Int, doubleResult: Bool) -> Int {
let sum = w + y
return doubleResult ? sum * 2 : sum
}
// Error: Invalid redeclaration of 'add(_:and:doubleResult:)'