Swift函數

jopen 8年前發布 | 10K 次閱讀 Swift Apple Swift開發

前言

Swift統一的函數語法足夠靈活,可以用來表示任何函數,包括從最簡單的沒有參數名字的 C 風格函數,到復雜的帶局部和外部參數名的Objective-C風格函數。參數可以提供默認值,以簡化函數調用。參數也可以既當做傳入參數,也當做傳出參數,也就是說,一旦函數執行結束,傳入的參數值可以被修改。

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

注明:Swift版本為2.1測試環境:xcode 7.2

函數定義與調用(Defining and Calling Functions)

函數定義語法為:func 函數名(參數列表) ->返回值:

 
// 函數定義方式:func 函數名稱(arg...) ->ReturnValue
functestFunc() ->Void {
  // 無參數,無返回值
}
 

若無返回值,可以直接省略 ->Void :

 
functestArgFunc(arg: Int) {
  // 無返回值可以使用Void,其實是空元組
}
 

我們先來看看官方定義的 Void 是什么:

 
/// The empty tuple type.
///
/// This is the default return type of functions for which no explicit
/// return type is specified.
publictypealiasVoid = ()
 

它其實就是一個空元組。它是作為函數無顯示指定返回類型時的默認返回值類型。

參數列表可以使用可變參數:

 
// 可變參數
funccalSum(array: Int...) ->Int {
  varsum = 0
  
  foritemin array {
    sum += item
  }
  
  return sum
}
 

函數調用就是通過我們的函數名稱調用:

 
calSum(1, 2, 3) // 6
calSum(1, 2) // 3
 

swift支持函數重載:

 
// 函數重載
funccalSum(array: [Int]) ->Int {
  varsum = 0
  
  foritemin array {
    sum += item
  }
  
  return sum
}
 
// 調用方式與上面一樣,只是參數類型不一樣
calSum([1, 2, 3])// 6
calSum([1, 4, 5]) // 10
 

函數有多個參數時,使用逗號分開,像: (arg1: Int, arg2, Int, arg3: Int) :

 
funcmultipleFunc(arg1: Int, _arg2: Int) ->Int {
  return 0
}
 

多重返回值函數(Functions with Multiple Return Values)

當函數有多個返回值時,我們可以使用元組作為返回值,當然也可以使用數組、字典等,但是使用元組更簡單,更明確:

 
funcminMax(array: [Int]) -> (min: Int,max: Int) {
    varcurrentMin = array[0]
    var currentMax = array[0]
    for valuein array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
 

Optional返回值類型

當函數不一定有返回值時,可以返回可選類型,在類型后面添加個問號即可:

 
funcminMax(array: [Int]) -> (min: Int,max: Int)? {
    if array.isEmpty { return nil }
    varcurrentMin = array[0]
    var currentMax = array[0]
    for valuein array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
 
// 調用的時候,通過值綁定來判斷是否有值
if letbounds = minMax([8, -6, 2, 109, 3, 71]) {
    print("min is \(bounds.min) and max is \(bounds.max)")
}
// prints "min is -6 and max is 109"
 

指定外部參數名(Specifying External Parameter Names)

我們看看Dictonary的一個API:

 
publicmutatingfuncremoveAll(keepCapacity keepCapacity: Bool = default)
 

我們可以看到這里一個參數有兩個名字:keepCapacity,其中第一個叫外部參數名,第二個叫函數內部變量。

比如,with是外部參數名,用于在調用時顯示的;而userId是函數內部變量名,用于內部使用:

 
funcfind(withuserId: Int) ->User? {
  
}
 
if letuser = find(with: 10) {
  // find
}
 

默認參數值(Default Parameter Values)

默認參數要放在參數列表最后:

 
funcsomeFunction(parameterWithDefault: Int = 12) {
    // function body goes here
    // if no arguments are passed to the function call,
    // value of parameterWithDefault is 12
}
someFunction(6) // parameterWithDefault is 6
someFunction() // parameterWithDefault is 12
 

可變參數(Variadic Parameters)

可變參數可以接收多個參數:

 
// 可變參數  
// 可變參數接受0個或者多個指定類型的值。可變參數使用...表示  
// 函數最多只能有一個可變參數,并且如果有可變參數,這個可變參數必須出現在參數列表的最后  
// 如果參數列表中有一或多個參數提供默認值,且有可變參數,那么可變參數也要放到所有最后一個  
// 提供默認值的參數之后(先是默認值參數,才能到可變參數)  
funcarithmeticMean(numbers: Double...) -> Double {  
  vartotal = 0.0  
  fornumberin numbers {  
    total += number  
  }  
  return total / Double(numbers.count)  
}  
  
arithmeticMean(1, 2, 3, ,4 5) // return 3.0  
arithmeticMean(1, 2, 3) // return 2.0  
 

常量參數和變量參數(Constant and Variable Parameters)

函數參數默認是常量。試圖在函數體中更改參數值將會導致編譯錯誤。這意味著你不能錯誤地更改參數值。

如果要在函數內部修改參數值,那么需要手動聲明為變量類型:

 
// 常量和變量參數  
// 在函數參數列表中,如果沒有指定參數是常量還是變量,那么默認是let,即常量  
// 這里Str需要在函數體內修改,所以需要指定為變量類型,即用關鍵字var  
funcalignRight(varstr: String,count: Int,pad: Character) -> String {  
  letamountToPad = count - countElements(str)  
    
  // 使用_表示忽略,因為這里沒有使用到  
  for _ in 1...amountToPad {  
    str = pad + str  
  }  
    
  return str  
} 
 

輸入輸出參數(In-Out Parameters)

 
// 輸入/輸出參數  
// 有時候,在函數體內修改了參數的值,如何能直接修改原始實參呢?就是使用In-Out參數  
// 使用inout關鍵字聲明的變量就是了  
// 下面這種寫法,是不是很像C++中的傳引用?  
funcswap(inoutlhs: Int, inoutrhs: Int) {  
  lettmp = lhs  
  lhs = rhs  
  rhs = tmp  
}  
 
// 如何調用呢?調用的調用,對應的實參前面需要添加&這個符號  
// 因為需要修改,所以一定是var類型的  
varfirst = 3  
varsecond = 4  
// 這種方式會修改實參的值  
swap(&first, &second) // first = 4, second = 3  
 

函數類型(Function Types)

 
// 使用函數類型  
// 這里是返回Int類型  
// 函數類型是:(Int, Int) -> Int  
funcaddTwoInts(first: Int,second: Int) -> Int {  
  return first + second  
}  
 
// 函數類型是:(Int, Int) -> Int  
funcmultiplyTwoInts(first: Int,second: Int) -> Int {  
  return first* second  
}  
 

使用函數類型(Using Function Types)

函數類型也需要類型,也可以用于定義變量,只是它是函數指針類型變量:

 
var mathFunction: (Int, Int) -> Int = addTwoInts  
 
mathFunction(1, 2) // return 3  
 
mathFunction = multiplyTwoInts  
 
mathFunction(1, 2) // return 2  
 

函數類型作為參數類型(Function Types as Parameter Types)

函數類型也是類型,也可以作為函數的形參:

 
// 函數類型可以作為參數  
funcprintMathResult(mathFunction: (Int, Int) -> Int,first: Int,second: Int) {  
  println("Result: \(mathFunction(first, second))")  
}  
  
printMathResult(addTwoInts, 3, 5) // prints "Result: 8"  
printMathResult(multiplyTwoInts, 3, 5) // prints "Result: 15"  
 

函數類型作為返回類型(Function Types as Return Types)

函數類型也可以作為返回值類型:

 
// 函數作為返回類型  
funcstepForward(input: Int) -> Int {  
  return input + 1  
}  
  
funcstepBackward(intput: Int) -> Int {  
  return input - 1  
}  
  
funcchooseStepFunction(backwards: Bool) -> ((Int) -> Int) {  
  return backwards ?stepBackward: stepForward  
}  
  
varcurrentValue = 3  
letmoveNearerToZero = chooseStepFunction(currentValue > 0) // call stepBackward() function  
  
// 參數可以嵌套定義,在C、OC中是不可以嵌套的哦  
funcchooseStepFunction(backwards: Bool) -> ((Int) -> Int) {  
  funcstepForward(input: Int) -> Int {  
    return input + 1  
  }  
    
  funcstepBackward(input: Int) -> Int {  
    return input + 1  
  }  
    
  return backwards ? stepBackward : stepForward  
}  
 

嵌套函數(Nested Functions)

在Ojbective-C中,函數是不能嵌套定義的,但是在swift中是可以嵌套的:

 
funcchooseStepFunction(backwards: Bool) -> (Int) -> Int {
    funcstepForward(input: Int) -> Int { return input + 1 }
    funcstepBackward(input: Int) -> Int { return input - 1 }
    return backwards ?stepBackward: stepForward
}
 
varcurrentValue = -4
letmoveNearerToZero = chooseStepFunction(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!
 

寫在最后

本篇博文是筆者在學習Swift 2.1的過程中記錄下來的,可能有些翻譯不到位,還請指出。另外,所有例子都是筆者練習寫的,若有不合理之處,還望指出。

學習一門語言最好的方法不是看萬遍書,而是動手操作、動手練習。如果大家喜歡,可以關注哦,盡量2-3天整理一篇Swift 2.1的文章。這里所寫的是基礎知識,如果您已經是大神,還請繞路!

關注我

如果在使用過程中遇到問題,或者想要與我交流,可加入有問必答 QQ群: 324400294

關注微信公眾號: iOSDevShares

關注新浪微博賬號:標哥Jacky

支持并捐助

如果您覺得文章對您很有幫助,希望得到您的支持。您的捐肋將會給予我最大的鼓勵,感謝您的支持!

支付寶捐助 微信捐助

來自: http://www.henishuo.com/functions-of-swift/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!