標籤:
都希望擁有一個既有長度又有厚度的人生
有多少人能在眼花繚亂的紛繁世界下,理智的區應對?
又有幾個人能將一件事堅持做10年?
想走在前面,需要明智的選擇和堅守的恒心,也需要智慧和高效的自我管理!
六、函數和閉包
函數: 執行特定任務的一段代碼
目的是複用,或者嵌套。
閉包:匿名函數,可以作為運算式,函數參數,函數傳回值,讓程式更簡潔。
聲明函數 func
無傳回值的3種聲明方式
1、省略 ->傳回值類型
2、->() 空
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
函數重載 多個同名函數,只是參數表,傳回值類型不同
閉包
1、無func 無函數名
2、使用in關鍵字(可省略)
3、第一個花括弧,移動到形參表的圓括弧之前
4、省略return
5、省略參數名
6、$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)// [孫悟空,孫悟空,孫悟空,孫悟空]
swift學習筆記6