都但願擁有一個既有長度又有厚度的人生swift
有多少人能在眼花繚亂的紛繁世界下,理智的區應對?數組
又有幾我的能將一件事堅持作10年?閉包
想走在前面,須要明智的選擇和堅守的恆心,也須要智慧和高效的自我管理!app
6、函數和閉包ide
函數: 執行特定任務的一段代碼函數
目的是複用,或者嵌套。ui
閉包:匿名函數,能夠做爲表達式,函數參數,函數返回值,讓程序更簡潔。spa
聲明函數 func指針
無返回值的3種聲明方式遞歸
一、省略 ->返回值類型
二、->() 空
三、->void
誰調用函數,誰負責給形參賦值。
func max(x:Int,y:Int)->Int
{
var z = x>y?x:y
return z
}
func sayHi(name:String)->String
{
return "\(name),你好!"
}
調用
var a = 6 ,b=5
var result = max(a,b)
println(sayHi("renhairui"))
實戰:定義個函數,返回指定的Double數值整數部分和2位小數部分
func divide(num:Double)->(String,String)
{
var zheng = Int64(num)
var xiao = round((num-Double(zheng))*100)
return ("\(zheng)","\(xiao)")
}
調用
var test = divide(123.456)
println("整數:\(test.0),小數:\(test.1)")
實戰 找出數組中最大,最小值
func getMaxAndMin(nums:[Int])->(max:Int,min:Int)
{
var max = nums[0],min = nums[0]
for num in nums
{
if num>max {
max = num
}
if num <min{
min = num
}
}
return (max,min)
}
調用
var nums = [20,30,5,89,100,2,6,-1]
var result = getMaxAndMin(nums)
println("最大值爲:\(result.max),最小值爲:\(result.min)")
遞歸函數:函數中調用自身,隱式循環,重複執行某一段代碼
實戰 已知數列 f(0) = 1,f(1) = 4,f(n+2) = 2*f(n+1) +f(n)
func fn(n:Int)->Int
{
if n == 0{
return 1
}else if n ==1{
return 4
}else{
return 2*fn(n-1)+fn(n-2)
}
}
遞歸是很是有用的,遍歷某個路徑下的全部文件,且深度是未知的。
外部形參
func girth(#width:Double,#height:Double)->Double
{
return Double(2)*(width+height)
}
調用
println(girth(width:12,height:22.5))
形參默認值
#height:Double = 20.3
println(girth(width:12))
取消默認值形參的外部參數名
_ height:Double = 20.3
可變形參,放在參數表最後
func test (a:Int,books:String ...)
{
for temp in books
{
println(temp)
}
println(a)
}
test(3,"swift","renhairui","ok")
變量形參 func girth(var #width:Double,#height:Double)->Double
{
width = (width + height)*2
return width
}
// 避免函數體內 從新定義新變量
調用
var w = 3.2
println(girth(width:w,height:12.9))
println(w) // 3.2
inout 形參
函數體內能夠修改 參數的值
func swap(inout a:Int,inout b:Int)
{
let tmp = a
a = b
b = temp
}
&對參數進行賦值才行,
調用
var a = 6 ,b= 9
swap(&a,&b)
已經實現交換!
實質:強制傳遞變量指針。
無論是值類型的參數仍是引用類型的參數,swift 都只是將參數的副本傳入函數內, 值類型參數傳遞-->值自己副本
引用類型參數傳遞-->引用的副本
函數類型
var myfun:(Int,Int)->Int // 類型是 (Int,Int)->Int
通常會把一個函數複製給它 變量類型要一致
函數類型的形參就是在調用函數時,動態傳入函數,命令模式!
函數類型能夠做爲返回值類型
實戰
func square(val:Int)->Int
{
return val * val
}
func cube (val:Int)->Int
{
return val* val *val
}
// 計算階乘
func factorial (val:Int)->Int
{
var result = 1
for index in 2...val
{
result *=index
}
return result
}
定義函數:返回值類型 (Int)->Int
func getMathFunc (#type:String)->(Int)->Int
{
switch(type)
{
case "sqsuare":
return square
case "cube":
return cube
defalut:
return factorial
}
}
調用
var mathFunc = getMathFunc (tpye:"cube")
// 輸出 125
println(mathFunc(5))
mathFunc = getMathFunc(type:"other")
println(mathFunc(5)) //120
函數重載 多個同名函數,只是參數表,返回值類型不一樣
閉包
一、無func 無函數名
二、使用in關鍵字(可省略)
三、第一個花括號,移動到形參表的圓括號以前
四、省略return
五、省略參數名
六、$0 $1表明參數
var square:(Int)->Int = {$0*$1}
println(square(5))
// 25
尾隨閉包 trailing closure 若是調用函數的最後一個參數是閉包,就將{}提出來放在最後
someFunc (20,{}) 這種--> someFunc(20){}
func map (var #data:[Int],#fn:(Int)->Int)->[Int]
{
for var i= 0, len = data.count;i<len:i++
{
data[i] = fn(data[i])
}
return data
}
var dataArr = [3,4,6,5,7]
var rvt1 = map(data:dataArr){$0*$0} // 計算元素平方
var rvt2 = map(data:dataArr){$0*$0*$0} //計算元素立方
// 計算元素階乘 不能省略return
var rvt3 = map(data:dataArr){
var result = 1
for index in 2...$0
{
result * = index
}
return result
}
捕獲 :閉包 能夠訪問或修改上下文中的變量和常量(只能訪問不能修改)
即便做用域不存在也不要緊
經常使用於 嵌套函數中
func makeArray(ele:String)->()->[String]
{
var arr:[String]=[]
func addElement() ->[String]
{
arr.append(ele)
return arr
}
}
上邊代碼中 arr ,ele捕捉了上下文中的變量,每一個閉包會持有一個它捕獲的變量副本
調用
let addBody = makeArray("renhairui")
println(addBody) // [renhairui]
println(addBody) //[renhairui,renhairui]
let addOther = makeArray("孫悟空")
println(addOther) // [孫悟空]
println(addOther) // [孫悟空,孫悟空]
輸出是兩個孫悟空
閉包是引用類型,因此,把一個閉包複製給兩個引用變量時,程序並不會複製他們,讓他們都指向同一個閉包
let addTest = addOther
println(addTest)// [孫悟空,孫悟空,孫悟空]
println(addTest)// [孫悟空,孫悟空,孫悟空,孫悟空]