函數式用來完成特定任務的獨立的代碼塊.咱們給一個函數起一個合適的名字,用來表示函數作什麼,而且當函數須要執行時,這個名字會被"調用".面試
在Swift中,每一個函數都有一種類型,包括函數的參數值類型和返回值類型.咱們能夠吧函數類型當作任何其餘普通變量類型同樣處理,這樣就能夠更簡單地吧函數當作別的函數參數,也能夠從其餘函數中返回函數.函數的定義能夠寫在其餘函數定義中,這樣能夠在嵌套函數範圍內實現功能封裝.swift
當咱們定義一個函數時,能夠定義一盒或多個有名字的值,做爲函數的輸入(參數,parameters),也能夠定義某種類型值做爲函數執行結束的輸出(返回類型,return type). 每一個函數有個函數名,用來描述函數執行的任務.要使用一個函數式罵咱們用函數名"調用",而且傳入它匹配的輸入值(實參,araguments).一個函數的實參必須與咱們函數參數表裏的參數的順序一致.如:數組
func sayHello(name: String) -> String {
let say = "hello,\(name)"
return say
}
print(sayHello(name: "kobe"))
out:
hello,kobe
複製代碼
全部的這些信息彙總起來成爲函數的定義,並一 func 做爲前綴.指定函數返回類型時,用返回箭頭 -> 後跟返回類型的名稱的方式來表示. 該定義描述了作什麼,它指望接受什麼和執行結束時返回的結果是什麼.這樣的定義使得函數能夠在別的地方以一種清晰的方式調用.bash
函數參數和返回值在swift中極爲靈活.咱們能夠定義任何類型的漢斯頓,包括從值帶一個未名參數的簡單函數到互砸的帶有表達性參數數名和不一樣參數選項的複雜函數閉包
函數能夠有多個輸入參數,寫在圓括號中,㐈逗號分隔.如:函數
func getMoney(number: Int, number1: Int) -> Int {
return number1 - number1
}
print("result:\(getMoney(number: 2, number1: 1))")
out:
result:0
複製代碼
函數能夠沒有參數,下面這個函數就是一個無參函數,當它被調用時,返回固定的String消息:網站
func sayHi() -> String {
return "hi, kebe"
}
print("sayHi:\(sayHi())")
out:
sayHi:hi, kebe
複製代碼
函數能夠沒有返回值,下面試sayHello函數的另外一個版本,函數直接輸出String,特不是返回他ui
func sayHello(name: String) {
print("hello,\(name)")
}
sayHello(name: "kobe")
out:
hello,kobe
複製代碼
咱們能夠用元組(tuple)類型讓鎖哥值做爲一個複合值從函數中返回,如:spa
func getMinMax(array: [Int]) -> (min: Int, max: Int) {
var min = array[0], max = array[0]
for item in array {
if item < min {
min = item
}
if item > max {
max = item
}
}
return (min,max)
}
let values = getMinMax(array: [1,2,3])
print("min:\(values.min),max:\(values.max)")
out:
min:1,max:3
複製代碼
返回多個值,咱們使用元組,而且添加可選類型,如:.net
func getMinMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty {
return nil
}
var min = array[0], max = array[0]
for item in array {
if item < min {
min = item
}
if item > max {
max = item
}
}
return (min,max)
}
let numbs = [Int]()
if let values = getMinMax(array: numbs) {
print("min:\(values.min),max:\(values.max)")
} else {
print("沒有數據")
}
out:
沒有數據
複製代碼
函數的參數,通常有外部參數名稱(咱們稱爲參數別名)和本地參數名稱(咱們成爲參數).外部參數名稱(參數別名)用於更好地讓函數調用者當即這一參數的意思,本地參數名稱(參數)用於在函數體中被實際調用.
在調用函數時,給每一個參數命名是很是有用的,由於這些參數名能夠支持各個實參的用途是什麼. 若是咱們但願函數的使用者在調用函數式提供參數名字,那麼久須要給玫瑰參數除了局部參數名外再定義一個外部參數名. 外部參數名寫在局部參數名以前,用空格分割,如:
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
return s1 + joiner + s2
}
print(join(string: "hello,", toString: "be", withJoiner: "ko"))
out:
hello,kobe
複製代碼
咱們能夠在函數體重爲每一個參數定義默認值.當默認值被定義後,爲調用這個函數時,若是沒有參數值,則使用參數定義的默認值,如:
func isStudent(name username: String, age: Int = 20) -> Bool {
var result: Bool = false
if age < 30 {
result = true
}
if username == "kobe" {
result = true
}
print("\(username) \(result ? "是學生" : "不是學生")")
return result
}
isStudent(name: "kobe")
isStudent(name: "zhangsan",age: 30)
out:
kobe 是學生
zhangsan 不是學生
複製代碼
一個可變參數"variadic parameter" 能夠接受一個或多個值. 當函數調用時,咱們能夠用可變參數來傳入不正確數量參數.經過在變量類型候命加入"..."的方式來定義可變參數. 傳入可變參數的值在函數體內定作這個類型的一個數組,瞭如,一個叫做numbers的Int...型可變參數,在函數體內能夠當作一個叫做numbers的Int[]型的數組常量,以下面的例子:
func sums(numbers: Int...) -> String {
var sum: Int = 0
var min = numbers[0]
var max = numbers[0]
for value in numbers {
sum += value
if value > max {
max = value
}
if value < min {
min = value
}
}
return "總和爲:\(sum),最大值爲:\(max),最小值爲:\(min)"
}
print(sums(numbers: 1,2,3,4,5))
out:
總和爲:15,最大值爲:5,最小值爲:1
複製代碼
函數參數默認是常量.視圖在函數體制那個更改參數值將會致使編譯錯誤.這意味着咱們不能錯過地更改參數值.可是有時候,若是函數中有傳入參數的變量值副本警示頗有用的.咱們能夠經過制定一個或多個參數爲變量參數,從而避免本身在函數中定義新的變量.變量參數不是常量,能夠在函數中把它當作新的可修改副原本使用,經過在參數明前加關鍵字 var 來定義參數,如:
func addChange( originstring s1: String, addString s2: String) -> String {
var s3 = s1 // 轉換成變量
s3 = "---" + s3
return s3 + s2
}
print("hi to \(addChange(originstring: "hi", addString: "hello"))")
out:
hi to ---hihello
複製代碼
變量參數,如上所述,僅能在函數體內被更改.若是咱們想要一個函數能夠修改參數的值,而且星耀在這些修改在函數調用結束後仍然存在,那麼久應該吧這些參數定義爲輸入輸出參數 "In-Out parameter". 定義一個輸入-輸出參數時,在參數定義前加"inout"關鍵字. 一個輸入-輸出參數有傳入函數的值,這個值被函數修改,而後被傳出函數替換原來的值.
注意,輸入-輸出參數不能有默認值,並且可變參數不能用inout表示,若是用"inout"標識一個參數,這個參數不能被var 或 let 標記. 以下面的例子:
// 這個函數式將a 和 b 的值互換
func swapTwoInts(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var a1 = 100
var b1 = 200
// 調用輸出參數的值是喲昂加&符號到參數
swap(&a1, &b1)
print("a1:\(a1), b1:\(b1)")
out:
a1:200, b1:100
複製代碼
每一個函數都有特定的函數類型,由函數的參數類型和返回類型組成.
在swift中,使用函數類型就像使用其餘類型同樣,如:
func add(a: Int, b: Int) -> Int {
return a + b
}
func multipy(a: Int, b: Int) -> Int {
return a * b
}
// 能夠這樣定義函數變量
var tmp1 = add
var tmp2: (Int, Int) -> Int = multipy
// 函數變量的使用
print("1 + 1 = \(tmp1(1,1))")
print("1 * 2 = \(tmp2(1,2))")
out:
1 + 1 = 2
1 * 2 = 2
複製代碼
當把函數類型當作參數使用時,咱們能夠將函數的一部分實行交給函數的調用者,如:
func showMulipy(a: Int, b: Int, mutipy: (Int, Int) -> Int) {
let result = multipy(a: a , b: b)
print("\(a) * \(b) = \(result)")
}
showMulipy(a: 1, b: 3, mutipy: multipy)
out:
1 * 3 = 3
複製代碼
能夠看出 "mutipy"是個閉包(其實,函數只是閉包的一種特殊形式)
咱們可使用函數類型做爲另外一個函數的返回類型.咱們須要作的是在返回箭頭 -> 後寫一個完整的函數類型,如:
func addOne(number: Int) -> Int {
return number + 1
}
func minusOne(number: Int) -> Int {
return number - 1
}
func isAddOrMinus(result: Bool) -> (Int)-> Int {
return result ? addOne : minusOne
}
print("調用函數類型做爲返回值:\(isAddOrMinus(result: (1 > 0))(10))")
out:
調用函數類型做爲返回值:11
複製代碼
繼續將上面例子的擴展,咱們能夠吧函數類型做爲常量使用,如:
var num = 10
let fuc = isAddOrMinus(result: num > 11)
while num != 0 {
print("\(num)", "terminator: ")
num = fuc(num)
}
out:
10 terminator:
9 terminator:
8 terminator:
7 terminator:
6 terminator:
5 terminator:
4 terminator:
3 terminator:
2 terminator:
1 terminator:
複製代碼
本節所見到的全部函數都常做爲全局函數(global funcation), 他們定義在全局域中. 咱們也能夠把函數定義在別的函數體重,稱做爲嵌套函數(nested functions). 在默認狀況下,嵌套漢是對外界不可見的,可是能夠被其封閉函數來調用.一個封閉函數也能夠返回他的某一個嵌套函數,似的這個函數能夠在其餘域中被使用.如:
func getResult(result: Bool) -> (Int,Int) -> Int {
func raise(a: Int, b: Int) -> Int {
return a + b
}
func cut(a: Int, b: Int) -> Int {
return a - b
}
return result ? raise : cut
}
// 定義常量函數
let fun = getResult(result: true)
// 調用嵌套的函數類型
var result = fun(100, 50)
print("reuslt:\(result)")
out:
reuslt:150
複製代碼
微博:順揚sky
簡書:順揚sky
掘金:順揚sky