Swift學習筆記第四篇(函式)

Deft_MKJing宓珂璟發表於2017-06-21

函式

在 Swift 中,每個函式都有一種型別,包括函式的引數值型別和返回值型別。你可以把函式型別當做任何其他普通變數型別一樣處理,這樣就可以更簡單地把函式當做別的函式的引數,也可以從其他函式中返回函式。函式的定義可以寫在在其他函式定義中,這樣可以在巢狀函式範圍內實現功能封裝。

單引數

/// 單引數
///
/// - Parameter personName: 引數1
/// - Returns: 返回型別
func sayHello(personName:String) -> String
{
    let greeting = "Hellow," + personName + "!"
    return greeting
}

print(sayHello(personName: "MKJ"))

多引數

/// 多引數
///
/// - Parameters:
///   - num1: 引數1
///   - num2: 引數2
/// - Returns: 返回型別
func delataTwoNumber(num1:Int, num2:Int) -> Int
{
    return num1 - num2
}

print(delataTwoNumber(num1: 10, num2: 1))

let funcD = delataTwoNumber
funcD(11,111)

無引數

/// 無引數
///
/// - Returns: 返回型別
func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())

func printSingleSlogan(slogan:String){
    print("woca,"+slogan + "!")
}

printSingleSlogan(slogan: "CJJ")

預設引數

/// 預設引數名
///
/// - Parameters:
///   - string1: 引數1
///   - string2: 引數2
///   - joiner: 引數3
/// - Returns: 返回值
func join(string1:String,string2:String,joiner:String = "+") -> String
{
    return string1 + joiner + string2
}

print(join(string1: "我", string2: "你")) // "我+你\n"
print(join(string1: "他", string2: "她", joiner: "0")) // "他0她\n"

可變引數

一個可變引數(variadic parameter)可以接受一個或多個值。函式呼叫時,你可以用可變引數來傳入不確定數量的輸入引數。通過在變數型別名後面加入(…)的方式來定義可變引數。
傳入可變引數的值在函式體內當做這個型別的一個陣列

/// 可變引數
///
/// - Parameter numers: 引數陣列
/// - Returns: 返回值
func total(numers:Double...) -> Double
{
    var totalD  = 0.0
    for numer in numers {
        totalD += numer
    }
    return totalD / Double(numers.count)
}



print("total is " + "\(total(numers: 2,10,21))")

輸入輸出引數(inout)

變數引數,正如上面所述,僅僅能在函式體內被更改。如果你想要一個函式可以修改引數的值,並且想要在這些修改在函式呼叫結束後仍然存在,那麼就應該把這個引數定義為輸入輸出引數(In-Out Parameters)。

定義一個輸入輸出引數時,在引數定義前加 inout 關鍵字。一個輸入輸出引數有傳入函式的值,這個值被函式修改,然後被傳出函式,替換原來的值。

你只能將變數作為輸入輸出引數。你不能傳入常量或者字面量(literal value),因為這些量是不能被修改的。當傳入的引數作為輸入輸出引數時,需要在引數前加&符,表示這個值可以被函式修改。

注意: 輸入輸出引數不能有預設值,而且可變引數不能用 inout 標記。如果你用 inout 標記一個引數,這個引數不能被 var 或者 let 標記。

/// 輸入輸出引數
///
/// - Parameters:
///   - a: 外部變數地址a
///   - b: 外部變數地址b
func swapTwoInts( a: inout Int, b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
//swapTwoInts(a: &someInt, b: &anotherInt)
swapTwoInts(a: &someInt, b: &anotherInt)
print("\(someInt)" + "\(anotherInt)")

函式型別使用

(引數1,引數2,引數3) -> (返回值1,返回值2)
可以理解為傳入三個需要型別的引數,返回一個有兩個指定型別的元祖

/// 使用函式型別
///
/// - Parameters:
///   - a: 引數1
///   - b: 引數2
/// - Returns: 返回值
func add(a:Int,b:Int)->Int
{
    return a+b
}

func mutiby(a:Int,b:Int)->Int
{
    return a*b
}
// 指定函式型別
var mathFunction :(Int,Int) -> Int = add

print("Result:\(mathFunction(2,3))")

mathFunction = mutiby

print("Result:\(mathFunction(3,5))")

// 自動推斷函式型別
let mathFunc = add
print("Result:\(mathFunc(2,5))")

我們申明變數指向函式的時候可以手動指定函式的型別,如果你不指定,swift會自動進行型別推斷

函式型別作為引數

/// 函式作為引數
///
/// - Parameters:
///   - a: <#a description#>
///   - b: <#b description#>
/// - Returns: <#return value description#>
func mathAdd(a:Int,b:Int) -> Int{
    return a+b
}

func printMathResult(mathFunc:(Int,Int)->Int,a:Int  ,b:Int){
    print("Result-->\(mathFunc(a,b))")
}

printMathResult(mathFunc: mathAdd, a: 3, b: 14)

printMathResult 函式的作用就是輸出另一個合適型別的數學函式的呼叫結果。它不關心傳入函式是如何實現的,它只關心這個傳入的函式型別是正確的。這使得 printMathResult 可以以一種型別安全(type-safe)的方式來保證傳入函式的呼叫是正確的。

函式作為型別返回

你可以用函式型別作為另一個函式的返回型別。你需要做的是在返回箭頭(->)後寫一個完整的函式型別。

/// 函式作為返回值
///
/// - Parameter number: <#number description#>
/// - Returns: <#return value description#>
func goForward(number:Int)->Int{
    return number + 1
}

func goBackward(number:Int)-> Int{
    return number - 1
}

func chooseStepFunction(chooseFlag:Bool) -> (Int)->Int{

    return chooseFlag ? goBackward : goForward
}

var countingNumber = 3
let moveFunc = chooseStepFunction(chooseFlag:  countingNumber > 0)

while countingNumber != 0 {
    print(String(countingNumber))
    countingNumber = moveFunc(countingNumber)
}
print("0!")

/// 3 2 1 0!

巢狀函式

你所見到的所有函式都叫全域性函式(global functions),它們定義在全域性域中。你也可以把函式定義在別的函式體中,稱作巢狀函式(nested functions)。

/// 巢狀函式
///
/// - Parameter chooseFlag: <#chooseFlag description#>
/// - Returns: <#return value description#>
func nestChooseStepFunction(chooseFlag:Bool) -> (Int)->Int{
    func stepF(num:Int)->Int{return num + 1}
    func stepB(num:Int)->Int{return num - 1}
    return chooseFlag ? stepF : stepB
}

var countingNum = -5
let resultFunc = nestChooseStepFunction(chooseFlag: countingNum < 0)

while countingNum < 0 {
    print("\(countingNum)" + "!")
    countingNum = resultFunc(countingNum)
}
print("0!")
/*
 -5!
 -4!
 -3!
 -2!
 -1!
 0!
 */

相關文章