Swift 的 Function (函式) 介紹

分享給朋友:

如果有一個人,說他在寫程式從沒用過函式,那他一定不是寫程式的傢伙。函式無論在那個程式語言,都是一定會用到的手法,在 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 函式了喔!

以上是函式的基本使用方式,如果有問題或是將來有用到更高階的手法,再請留言讓我知道,我會再補充上去的喔!

分享給朋友:

發表迴響