1. 函數是用來完成特定任務的獨立的代碼塊。Swift中函數的使用比Java中更靈活,在 Swift 中,能夠把函數當作別的函數的參數,也能夠從其餘函數中返回函數。函數的定義能夠寫在在其餘函數定義中,這樣能夠在嵌套函數範圍內實現功能封裝。在函數的參數值類型和返回值類型方面,Swift和Java函數的用法是類似的。swift
2. 函數的申明和調用數組
Swift:函數
func sayHelloAgain(personName: String) -> String { return "Hello again, " + personName + "!" } print(sayHelloAgain("Anna")) // prints "Hello again, Anna!"
函數以 func
做爲前綴。指定函數返回類型時,用返回箭頭 ->
(一個連字符後跟一個右尖括號)後跟返回類型的名稱的方式來表示。spa
Java:code
public String sayHello(String personName){ return "hello, "+personName; } System.out.println(sayHello("morden"));
3. 函數參數與返回值(Function Parameters and Return Values)blog
3.1 多重輸入參數(Multiple Input Parameters)three
Swift:生命週期
func halfOpenRangeLength(start:Int, end:Int)->Int{ return end - start }
Java:ip
public int halfOpenRangeLength(int start, int end){ return end - start; }
3.2 無參函數(Functions Without Parameters)字符串
Swift:
func sayHelloWorld()->String{ return "hello world" }
Java:
public String sayHelloWorld(){ return "hello world"; }
3.3 無返回值函數(Functions Without Return Values)
Swift:
func sayGoodbye(personName:String){ print("GoodBye, \(personName)") }
Java:
public void sayGoodbye(String personName){ System.out.println("Goodbye, "+personName); }
注意:在返回值方面,Swift比Java語法靈活多了,看下面代碼
func printAndCount(stringToPrint: String) -> Int { print(stringToPrint) return stringToPrint.characters.count } func printWithoutCounting(stringToPrint: String) { printAndCount(stringToPrint) } printAndCount("hello, world") // prints "hello, world" and returns a value of 12 printWithoutCounting("hello, world") // prints "hello, world" but does not return a value
第一個函數 printAndCount
,輸出一個字符串並返回 Int
類型的字符數。第二個函數printWithoutCounting
調用了第一個函數,可是忽略了它的返回值。
3.4 多重返回值函數(Functions with Multiple Return Values)
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) { var vowels = 0, consonants = 0, others = 0 for character in string.characters { switch String(character).lowercaseString { case "a", "e", "i", "o", "u": ++vowels case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z": ++consonants default: ++others } } return (vowels, consonants, others) }
這個例子中,count
函數用來計算一個字符串中元音,輔音和其餘字母的個數(基於美式英語的標準)。
let total = count("some arbitrary string!") print("\(total.vowels) vowels and \(total.consonants) consonants") // prints "6 vowels and 13 consonants"
4. 外部參數名(External Parameter Names)
若是你但願函數的使用者在調用函數時提供參數名字,那就須要給每一個參數除了局部參數名外再定義一個外部參數名
。外部參數名寫在局部參數名以前,用空格分隔。外部參數名函數格式以下:
func someFunction(externalParameterName localParameterName: Int) { // function body goes here, and can use localParameterName // to refer to the argument value for that parameter }
Swift代碼以下:
func join(string s1 : String, toString s2 : String, withJoiner joiner: String)->String{ return s1 + joiner + s2 }
//調用函數 let temp = join(string: "hello", toString: "world", withJoiner: ", ") print(temp)
默認參數值(Default Parameter Values).你能夠在函數體中爲每一個參數定義默認值
。當默認值被定義後,調用這個函數時能夠忽略這個參數。代碼以下:
func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String { return s1 + joiner + s2 }
像第一個版本的 join
函數同樣,若是 joiner
被賦值時,函數將使用這個字符串值來鏈接兩個字符串:
join(string: "hello", toString: "world", withJoiner: "-") // returns "hello-world"
當這個函數被調用時,若是 joiner
的值沒有被指定,函數會使用默認值(" "):
join(string: "hello", toString:"world") // returns "hello world"
5. 可變參數(Variadic Parameters)
一個可變參數(variadic parameter)
能夠接受一個或多個值。函數調用時,你能夠用可變參數來傳入不肯定數量的輸入參數。經過在變量類型名後面加入(...)
的方式來定義可變參數。傳入可變參數的值在函數體內當作這個類型的一個數組。代碼以下:
func arithmeticMean(numbers:Double...){ var total : Double = 0 for item in numbers{ total += item } print("total is \(total)") } arithmeticMean(1, 2, 3, 4, 5) // returns 3.0, which is the arithmetic mean of these five numbers arithmeticMean(3, 8, 19) // returns 10.0, which is the arithmetic mean of these three numbers
注意:一個函數至多能有一個可變參數,並且它必須是參數表中最後的一個。這樣作是爲了不函數調用時出現歧義。若是函數有一個或多個帶默認值的參數,並且還有一個可變參數,那麼把可變參數放在參數表的最後。
6.
常量參數和變量參數(Constant and Variable Parameters)
函數參數默認是常量。試圖在函數體中更改參數值將會致使編譯錯誤。這意味着你不能錯誤地更改參數值。可是,有時候,若是函數中有傳入參數的變量值副本將是頗有用的。你能夠經過指定一個或多個參數爲變量參數,從而避免本身在函數中定義新的變量。變量參數不是常量,你能夠在函數中把它當作新的可修改副原本使用。經過在參數名前加關鍵字 var
來定義變量參數:
func alignRight(var string : String, count : Int, pad : Character)->String{ let amountToPad = count - string.characters.count if amountToPad < 1 { return string } let padString = String(pad) for _ in 1...amountToPad { string = padString + string } return string } let originalString = "hello" let paddedString = alignRight(originalString, 10, "-") // paddedString is equal to "-----hello" // originalString is still equal to "hello"
注意: 對變量參數所進行的修改在函數調用結束後便消失了,而且對於函數體外是不可見的。變量參數僅僅存在於函數調用的生命週期中。
7. 輸入輸出參數(In-Out Parameters)
變量參數,僅僅能在函數體內被更改。若是你想要一個函數能夠修改參數的值,而且想要在這些修改在函數調用結束後仍然存在,那麼就應該把這個參數定義爲輸入輸出參數(In-Out Parameters)。定義一個輸入輸出參數時,在參數定義前加 inout
關鍵字。一個輸入輸出參數有傳入函數的值,這個值被函數修改,而後被傳出函數,替換原來的值。你只能將變量做爲輸入輸出參數。你不能傳入常量或者字面量(literal value),由於這些量是不能被修改的。當傳入的參數做爲輸入輸出參數時,須要在參數前加&
符,表示這個值能夠被函數修改。注意: 輸入輸出參數不能有默認值,並且可變參數不能用 inout
標記。若是你用 inout
標記一個參數,這個參數不能被 var
者 let
標記。
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a = b b = temporaryA }
咱們能夠用兩個 Int
型的變量來調用 swapTwoInts
。須要注意的是,someInt
和 anotherInt
在傳入swapTwoInts
函數前,都加了 &
的前綴,代碼以下:
var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) print("someInt is now \(someInt), and anotherInt is now \(anotherInt)") // prints "someInt is now 107, and anotherInt is now 3」
從上面這個例子中,咱們能夠看到 someInt
和 anotherInt
的原始值在 swapTwoInts
函數中被修改,儘管它們的定義在函數體外。注意: 輸入輸出參數和返回值是不同的。上面的 swapTwoInts
函數並無定義任何返回值,但仍然修改了 someInt
和 anotherInt
的值。輸入輸出參數是函數對函數體外產生影響的另外一種方式。
8. 函數類型(Function Types
函數類型(Function Types:每一個函數都有種特定的函數類型,由函數的參數類型和返回類型組成。
8.1 申明函數類型,代碼以下:
func addTwoInts(a: Int, b: Int) -> Int { return a + b } func multiplyTwoInts(a: Int, b: Int) -> Int { return a * b }
8.2 使用函數類型(Using Function Types),代碼以下:
var mathFunction: (Int, Int) -> Int = addTwoInts print("Result: \(mathFunction(2, 3))") // prints "Result: 5" mathFunction = multiplyTwoInts print("Result: \(mathFunction(2, 3))") // prints "Result: 6"
8.3 函數類型做爲參數類型(Function Types as Parameter Types):你能夠用(Int, Int) -> Int
這樣的函數類型做爲另外一個函數的參數類型。這樣你能夠將函數的一部分實現交由給函數的調用者。代碼以下:
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // prints "Result: 8」
8.4 函數類型做爲返回類型(Function Type as Return Types)
咱們能夠用函數類型做爲另外一個函數的返回類型。須要作的是在返回箭頭(->
)後寫一個完整的函數類型。下面的這個例子中定義了兩個簡單函數,分別是 stepForward
和stepBackward
。stepForward
函數返回一個比輸入值大一的值。stepBackward
函數返回一個比輸入值小一的值。這兩個函數的類型都是 (Int) -> Int
:代碼以下:
func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 }
chooseStepFunction
根據布爾值 backwards
來返回 stepForward
函數或 stepBackward
函數:代碼以下:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int { return backwards ? stepBackward : stepForward }
如今能夠用 chooseStepFunction
來得到一個函數,不論是那個方向:
var currentValue = 3 let moveNearerToZero = chooseStepFunction(currentValue > 0) // moveNearerToZero now refers to the stepBackward() function
這個例子中計算出從 currentValue
逐漸接近到0
是須要向正數走仍是向負數走。currentValue
的初始值是3
,這意味着 currentValue > 0
是真的(true
),這將使得 chooseStepFunction
返回stepBackward
函數。一個指向返回的函數的引用保存在了 moveNearerToZero
常量中。
8.5 嵌套函數(Nested Functions)
你所見到的全部函數都叫全局函數(global functions),它們定義在全局域中。你也能夠把函數定義在別的函數體中,稱做嵌套函數(nested functions)。默認狀況下,嵌套函數是對外界不可見的,可是能夠被他們封閉函數(enclosing function)來調用。一個封閉函數也能夠返回它的某一個嵌套函數,使得這個函數能夠在其餘域中被使用。你能夠用返回嵌套函數的方式重寫 chooseStepFunction
函數:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int { func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } return backwards ? stepForward : stepBackward } @IBAction func Test(sender: AnyObject) { var currentValue = -4 let moveNearerToZero = chooseStepFunction(currentValue < 0) // moveNearerToZero now refers to the nested stepForward() function while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } }
// -4... // -3... // -2... // -1...