注意: 沒有定義返回類型的函數會返回特殊的值,叫 Void。它實際上是一個空的元組(tuple),沒有任何元素,能夠寫成()。
使用元組做爲返回參數,返回多個參數git
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) { var vowels = 0, consonants = 0, others = 0 for character in string { 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) }
外部參數名..是爲了調用該函數時讓其參數更爲有表現力,更爲通順,同時還保持了函數體是可讀的和有明確意圖的。讓別人閱讀整段代碼時更方便
當其餘人在第一次讀你的代碼,函數參數的意圖顯得不明顯時,考慮使用外部參數名。若是函數參數名的意圖是很明顯的,那就不須要定義外部參數名了數組
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String { return s1 + joiner + s2 } join(string: "hello", toString: "world", withJoiner: ", ")
若是你須要提供外部參數名,可是局部參數名已經定義好了,那麼你不須要寫兩次參數名。相反,只寫一次參數名,並用井號(#)做爲前綴就能夠了。這告訴 Swift 使用這個參數名做爲局部和外部參數名。閉包
func containsCharacter(#string: String, #characterToFind: Character) -> Bool { for character in string { if character == characterToFind { return true } } return false }
將帶有默認值的參數放在函數參數列表的最後。這樣能夠保證在函數調用時,非默認參數的順序是一致的,同時使得相同的函數在不一樣狀況下調用時顯得更爲清晰。
當你未給帶默認值的參數提供外部參數名時,Swift 會自動提供外部名字。此時外部參數名與局部名字是同樣的,就像你已經在局部參數名前寫了井號(#)同樣。函數
func join(s1: String, s2: String, joiner: String = " ") -> String { return s1 + joiner + s2 } join("hello", "world", joiner: "-") // returns "hello-world"
一個可變參數(variadic parameter)能夠接受一個或多個值.傳入可變參數的值在函數體內當作這個類型的一個數組。生命週期
func arithmeticMean(numbers: Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total / Double(numbers.count) }
函數參數默認是常量。試圖在函數體中更改參數值將會致使編譯錯誤。這意味着你不能錯誤地更改參數值
注意: 對變量參數所進行的修改在函數調用結束後便消失了,而且對於函數體外是不可見的。變量參數僅僅存在於函數調用的生命週期中。內存
func alignRight(var string: String, count: Int, pad: Character) -> String { let amountToPad = count - countElements(string) for _ in 1...amountToPad { string = pad + string } return string } //下面這樣會報錯 func test(a:String){ a = "sssss"; }
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a = b b = temporaryA } var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt);// "someInt is now 107, and anotherInt is now 3」
函數類型,可讓一個變量能夠成爲多個函數,同時能夠把函數當參數進行傳遞或者當作返回值rem
var mathFunction: (Int, Int) -> Int = addTwoInts func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { println("Result: \(mathFunction(a, b))") } func chooseStepFunction(backwards: Bool) -> (Int) -> Int { func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } return backwards ? stepBackward : stepForward }
閉包能夠捕獲和存儲其所在上下文中任意常量和變量的引用。 這就是所謂的閉合幷包裹着這些常量和變量,俗稱閉包。Swift 會爲您管理在捕獲過程當中涉及到的全部內存操做。
閉包表達式:input
{ (parameters) -> returnType in statements }
閉包做爲函數參數的話,因爲類型推斷...能夠省去閉包參數的類型和返回值閉string
reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } ) reversed = sorted(names, { s1, s2 in return s1 > s2 } )
包函數體內若是是單一表達式,還能夠省去return語句it
reversed = sorted(names, { s1, s2 in s1 > s2 } )
reversed = sorted(names, { $0 > $1 } ) reversed = sorted(names, >)
若是您須要將一個很長的閉包表達式做爲最後一個參數傳遞給函數,能夠使用尾隨閉包來加強函數的可讀性。 尾隨閉包是一個書寫在函數括號以後的閉包表達式,函數支持將其做爲最後一個參數調用。
let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine" ] let numbers = [16, 58, 510] let strings = numbers.map { (var number) -> String in var output = "" while number > 0 { output = digitNames[number % 10]! + output number /= 10 } return output }
閉包能夠在其定義的上下文中捕獲常量或變量。
即便定義這些常量和變量的原域已經不存在,閉包仍然能夠在閉包函數體內引用和修改這些值。
閉包是引用類型。可是注意,當一個嵌套函數內的函數做爲返回值的時候其實是建立了一個新的函數.
//全局函數 var str = "Hello, playground" func test(a:String=""){ println(str) } test(); //"Hello, playground" str = "Hello"; test(); //"Hello" //嵌套函數 func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount //runningTotal return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) incrementByTen() // 返回的值爲10 incrementByTen() // 返回的值爲20 incrementByTen() // 返回的值爲30 //因爲是建立了一個新函數..因此會像下面顯示 let incrementBySeven = makeIncrementor(forIncrement: 7) incrementBySeven() // 返回的值爲7 incrementByTen() // 返回的值爲40 //因爲是引用類型.因此 let alsoIncrementByTen = incrementByTen alsoIncrementByTen() // 返回的值爲50
注意: Swift 會決定捕獲引用仍是拷貝值。 您不須要標註amount或者runningTotal來聲明在嵌入的incrementor函數中的使用方式。 Swift 同時也處理runingTotal變量的內存管理操做,若是再也不被incrementor函數使用,則會被清除。