如果有一個人,說他在寫程式從沒用過函式,那他一定不是寫程式的傢伙。函式無論在那個程式語言,都是一定會用到的手法,在 Swift 中也必然!而在 Swift 中我們可以輕鬆使用函式,接下來在這一篇,將介紹 Swift 的函式如何使用!
func 參數名稱(參數名1: 資料型別1, 參數名2: 資料型別2) -> 回傳型態 {
//函式內容
return 返回值
}
舉例來說,我們可以將函式寫成下列。
func greet(person: String) -> String {
let greeting = "Hello, " + person + "!"
return greeting
}
接下來,我們再用「函式名稱(參數名1: 值1, 參數名2: 值2)」的方式來呼叫函式。
print(greet(person: "Anna"))
// Prints "Hello, Anna!"
print(greet(person: "Brian"))
// Prints "Hello, Brian!"
以上列例子來說,可能藏有一個風險,就是我們的「參數名稱」被猜到啦,也因此 Swift 將函式再改良,可以分成內外不同的參數名稱。
func 參數名稱(外部參數名1 內部參數名1: 資料型別1, 外部參數名2 內部參數名2: 資料型別2) -> 回傳型態 {
//函式內容
return 返回值
}
舉例來說,我們可以將上例改成以下這樣,這樣一來,person 就變外部參數名,name 才是函式可以使用的變數名稱。
func greet(person name: String) -> String {
let greeting = "Hello, " + name + "!"
return greeting
}
print(greet(person: "Anna"))
// Prints "Hello, Anna!"
print(greet(person: "Brian"))
// Prints "Hello, Brian!"
但如果我們每次都要打外部參數名稱,其實也變討人厭的,也不符合 Swift 懶人精簡的精神,所以我們可以用 _ 來取代外部參數名稱,這樣一來我們呼叫函式時,就不用打外部參數名啦!
func greet(_ name: String) -> String {
let greeting = "Hello, " + name + "!"
return greeting
}
print(greet(person: "Anna"))
// Prints "Hello, Anna!"
print(greet(person: "Brian"))
// Prints "Hello, Brian!"
如果我們的函式不需要任何參數呢?很簡單,只要將 () 中全部留空就好啦!
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())
// Prints "hello, world"
另一個情況,我們的函式不必回傳任何值,這時只要將「回傳型態改為()」就可以了。
func greet(_ name: String) -> () {
let greeting = "Hello, " + name + "!"
print(greeting)
}
greet("Anna")
// Prints "Hello, Anna!"
greet("Brian")
// Prints "Hello, Brian!"
Swift 追求精簡,當回傳的資料型別為空時,甚至連「-> ()」都不用寫。
func greet(_ name: String) {
let greeting = "Hello, " + name + "!"
print(greeting)
}
greet("Anna")
// Prints "Hello, Anna!"
greet("Brian")
// Prints "Hello, Brian!"
函式中一次傳多個參數的範例,在這個範例中,我們定義了兩個相同的函式名稱 greet,但因為參數個數不同,所以 Swift 會將他列為不同的函式,這也就是我們常聽到的多載 (Overloading)。
func greetAgain(person name: String) -> String {
let greeting = "Hello, " + name + " Again!"
return greeting
}
func greet(person name: String) -> String {
let greeting = "Hello, " + name + "!"
return greeting
}
func greet(person: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person)
}
}
print(greet(person: "Tim", alreadyGreeted: true))
// Prints "Hello again, Tim!"
結合了剛剛所說的,我們可以用 _ 來取代外部參數名稱,所以可以寫成更精簡。
func greetAgain(_ name: String) -> String {
let greeting = "Hello, " + name + " Again!"
return greeting
}
func greet(_ name: String) -> String {
let greeting = "Hello, " + name + "!"
return greeting
}
func greet(_ person: String, _ alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person)
} else {
return greet(person)
}
}
print(greet("Tim", true))
// Prints "Hello again, Tim!"
Swift 函式也可以給定預設值,當我們沒有傳值進去時,就會以預設值代替,舉例如下。
func greet(_ name: String = "海芋") -> String {
let greeting = "Hello, " + name + "!"
return greeting
}
print(greet("Tim"))
// Prints "Hello again, Tim!"
print(greet())
// Prints "Hello again, 海芋!"
Swift 中還有巢狀函式 (Nested Functions),在函式裡面可以在建立函式,巢狀內部的函式可以只在巢狀函式中使用,也可以讓外部使用,以下是一個範例。
func chooseStepFunction(backward: Bool) -> (Int) -> Int
{
func stepForward(input: Int) -> Int
{
return input + 1
}
func stepBackward(input: Int) -> Int
{
return input - 1
}
return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
在此範例中,因為 currentValue > 0 不成立,所以會執行 chooseStepFunction(false),這時 moveNearerToZero 就指向了 stepForward 函式了喔!
以上是函式的基本使用方式,如果有問題或是將來有用到更高階的手法,再請留言讓我知道,我會再補充上去的喔!