Swift function 參數的外部名 & 內部名(argument label & parameter name)
呼叫 function 包含參數名的好處
學過其它程式語言的朋友,也許會覺得 Swift 的呼叫 function 有點怪,比方以下例子,呼叫 eat 時 ( ) 裡必須包含參數名 name & price。
func eat(name: String, price: String) {
let message = "花了$" + price + "吃" + name
print(message)
}
eat(name: "英國頂極菲力牛排", price: "2500")
其它程式語言呼叫 function 時,往往不帶參數名,例如以下例子:
eat("英國頂極菲力牛排", "2500")
為什麼 Swift 要與眾不同,要我們額外輸入參數名呢 ?
這一切都是為了增加程式的可讀性。寫成沒有參數名的 eat("英國頂極菲力牛排", "2500")
, 我們很難一眼看出 2500 是 2500 元還是 2500 克 ? 除非我們特別去研究 function eat 定義的程式碼或註解。相反的,呼叫 function 時包含參數名稱,寫成 eat(name: "英國頂極菲力牛排", price: "2500")
,我們一眼就能看出它是 2500 元,因為參數名幫我們理解參數的意義。
function 參數的外部名 & 內部名(parameter name & argument label)
Swift 的 function 參數不僅於此,它可以有外部名和內部名兩種名稱,就像我們在外面跟家裡也常有不同名字。
例如以下例子,我們在 function { } 裡存取的參數名是內部名(parameter name),呼叫 function 時在 ( ) 裡包含的參數名是外部名(argument label)。
也許你會覺得奇怪,剛剛的例子裡,明明外部名和內部名一模一樣呀,哪有什麼分別? 其實在定義 function eat 時,我們在 eat(name: String, price: String)
裡宣告的 name & price 是參數的內部名,而 Swift 會自動幫我們產生和內部名同名的外部名。這也是我們最常使用的情境,畢竟為參數的外部名和內部名想不同名字是很累的一 件事,就好像生寶寶想名字一樣 !
大部分的時候,我們習慣採用 Swift 預設的設計,讓參數的外部名和內部名同名。只有在某些特別的情況,為了讓程式看起來更淺顯易懂,更像人類熟悉的英文句子,我們才會另外取不同的外部名。
讓我們看看以下的例子。
func move(start: String, end: String) {
print("move from " + start + " to " + end)
}
move(start: "地球", end: "火星")
以上程式完全沒問題,執行後將印出 move from 地球 to 火星
,不過呼叫 function 時寫成 move(start: "地球", end: "火星")
,看起來不太像英文句子。
寫程式時寫得愈像英文句子愈好,因為愈容易讓人理解。那如果將參數名改成 from & to 呢 ?
func move(from: String, to: String) {
print("move from " + from + " to " + to)
}
move(from: "地球", to: "火星")
呼叫 function 時變成 move(from: "地球", to: "火星")
,看起來像英文 句子了,但是 function 的 { } 裡卻變成 print("move from " + from + " to " + to)
,變成它不像英文句子了。
看來很難有一個名字同時適合 function 內部和 function 呼叫時使用。沒關係,我們還有最後的大絕招,讓參數的外部名和內部名不同名字。
宣告 function 參數時,參數的規則如下:
- 可同時包含外部名和內部名,先外部名再內部名,以空白隔開。
- 外部名可省略,但內部名則一定要有。只有內部名時, Swift 將自動產生同名的外部名。
func move(from start: String, to end: String) {
print("move from " + start + " to " + end)
}
move(from: "地球", to: "火星")
以上例子完美解決剛剛的問題,參數的外部名是 from & to,內部名是 start & end,,print("move from " + start + " to " + end)
& move(from: "地球", to: "火星")
看起來都像英文句子了。
接著讓我們再多看一個模仿 Apple 官方的例子。
func greet(person: String, from hometown: String) -> String {
return "Hello " + person + "! Glad you could visit from " + hometown + "."
}
print(greet(person: "Bill", from: "Cupertino"))
第二個參數的外部名是 from ,內部名是 hometown。從以上的例子,我們發現參數的外部名滿常出現英文的連接詞,比方 with,on,from,to 等,因為它們能讓呼叫 function 的程式看起來更像英文句子。
iOS SDK 參數外部名 & 內部名不同的例子
iOS SDK 裡許多 function 為了增加可讀性,參數的外部名 & 內部名取不同的名字,以下讓我們看看幾個例子。
- DateFormatter 的 function string(from:)。
參數的外部名是 from,內部名是 date。
func string(from date: Date) -> String
應用
import Foundation
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy年MM月dd日"
let dateString = dateFormatter.string(from: now)
結果
2022年03月26日
- Date 的 function advanced(by:)。
參數的外部名是 by,內部名是 n。
func advanced(by n: TimeInterval) -> Date
應用
import Foundation
var time1 = Date()
var time2 = time1.advanced(by: 60)
print(time1)
print(time2)
印出
2022-03-26 09:11:37 +0000
2022-03-26 09:12:37 +0000
AI 舉的例子
func exchangeGift(from personA: String, to personB: String) {
print("\(personA) gives a gift to \(personB)")
}
exchangeGift(from: "Alice", to: "Bob")
func orderFood(for customer: String, dish: String) {
print("\(customer) orders \(dish)")
}
orderFood(for: "小王子", dish: "牛排")
取消外部參數名(argument label)
呼叫 function 時,參數的外部名可以幫助我們理解參數的意義。不過有時我們可以一眼看出參數的意義,不需要額外的參數名稱說明。尤其是第一個參數,我們往往能從 function 名稱猜出它的意思。
例如以下例子,呼叫 function 時, eatFood(name: "美國頂級菲力牛排", price: "2500")
裡的 name 有點多餘,就算沒有 name,我們還是能猜出牛排是食物的名稱。
func eat(name: String, price: String) {
let message = "花了$" + price + "吃" + name
print(message)
}
eat(name: "英國頂極菲力牛排", price: "2500")
因此不如就省略外部參數名 name 吧。定義 function 時,將外部參數名宣告為 _ 即可省略。(ps: 在 Swift 裡當 _ 出現時,通常都和捨去、忽略有關)
func eat(_ name: String, price: String) {
let message = "花了$" + price + "吃" + name
print(message)
}
eat("英國頂極菲力牛排", price: "2500")
也因為 _ 的關係,呼叫 function 時,參數的提示輸入框有兩種,一種要帶參數名,一種不用,相關說明可參考以下連結。
iOS SDK 取消外部參數名(argument label) 的例子
開發 iOS App 時,其實很多地方都可以看到省略外部參數名,以下讓我們看看幾個不同的例子。
func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
呼叫 print 時可省略參數名 items。
print("明月幾時有,把酒問青天")
- String 的 append(_:)
func append(_ other: String)
呼叫 append 時可省略參數名 other,bestManName 變成 peter是好男人
。
var bestManName = "peter"
bestManName.append("是好男人")