در Swift، میتوانید چندین تابع با اسم یکسان تعریف کنید، تا زمانی که امضاهایشان متفاوت باشد. این کار به «سربارگذاری تابع» شناخته میشود.
تابع پایهی زیر را در نظر بگیرید:
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
در Swift، دو تابع با اسم یکسان در صورتی متمایز در نظر گرفته میشوند که هر یک از شرطهای زیر برقرار باشد:
با در نظر گرفتن تابع اصلی add در بالا، هر یک از سربارگذاریهای زیر در همان برنامه متمایز و معتبر است:
// 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
توابع را میتوان تنها بر اساس نوع بازگشتیشان نیز سربارگذاری کرد. اما هنگام فراخوانی چنین تابعی، باید یک حاشیهنویسی نوع یا بافت ارائه دهید تا کامپایلر بداند منظورتان کدام سربارگذاری است:
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
تغییر دادن فقط اسم پارامتر داخلی بدون تغییر برچسب آرگومان، نوع پارامتر یا تعداد پارامتر، تابع متمایزی ایجاد نمیکند. کامپایلر با این کار به عنوان یک اعلان تکراری نامعتبر برخورد میکند:
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:)'