1.函数
可变参数放最后,var参数只在函数内有效,函数形参默认let类型,inout参数地址传递。
函数新特性:
(1)函数可以通过返回元组实现返回多个参数,Void表示放回空元组。
函数类型的变量。
(2)函数可以作另一个函数的参数。
(3)函数可以作另一个函数的返回值,对于一个->表返回,后面的->表示返回值为一个函数。
//////////////////////////////part1 //函数 func sayHello(name:String?)->String{//->String表示返回一个字符串类型 let result = "hello,"+(name ?? "Guest")//当字符串为空时,name为guest return result; } var nickname:String?//声明一个可选型的字符串 println(sayHello(nickname)) //////////////////////////////part2 //通过元祖可以返回多个值 func maxminSores(score:[Int])->(maxscore:Int,minscore:Int)?{//返回一个可选值元祖 if score.isEmpty{//当数组为空时 return nil } var curmax = score[0],curmin = score[0]//初始化最大最小值为第一个数 for score in score[1..<score.count]//1到count-1 { curmax = max(curmax, score) curmin = min(curmin, score) } return (curmax,curmin) } var userScores:[Int]? = [12,990,572,3258,9999,1204] userScores = userScores ?? []//当数组为空时userScores=[] if let (maxV,minV) = maxminSores(userScores!){ maxV minV } //////////////////////////////part3 //保留oc特性中的外部参数名 //#表示外表参数名跟内部一致,定义函数允许赋予默认值,有默认值的参数要放在后面 func sayHi(userName name:String?,# greet:String,others:String=". how do you do")->String{//->String表示返回一个字符串类型 let result = "(greet),"+(name ?? "Guest")+others//当字符串为空时,name为guest return result; } sayHi(userName: "forr", greet: "hi") //////////////////////////////part4 //设置可变参数others:Int... //函数的参数排序:先是必须的参数,再到带默认值的参数,最后是可变的参数 //函数中的参数默认是let不可变的,且属于值传递, func add(var a:Int,b:Int,others:Int...)->Int{ var result = a+b for num in others{ result += num } a = 1000 return result } var a = 2 var res = add(a,3, 4) a ////////////////////////////part4 //通过inout声明参数实现“址传递” func swapTwoInts(inout a:Int,inout b:Int){ let t = a a = b b = t } var x = 0,y = 100 x y swapTwoInts(&x, &y) x y ////////////////////////////part5 //通过变量存在一个函数,此时给出变量的类型为:(Int,Int,Int...)->Int let anotherAdd:(Int,Int,Int...)->Int = add anotherAdd(6,3,1) func sayYes(){ print("yes") } let anotherSayYes:()->() = sayYes sayYes() ////////////////////////////part6 //将一个函数用作另一个函数的参数,:(Int)->Int表示变量的类型是一个函数类型 func changeScores(op:(Int)->Int,inout scores:[Int]){ for i in 0..<scores.count{ scores[i] = op(scores[i])//调用函数op(scores[i]) } } func op1(x:Int)->Int{return Int(sqrt(Double(x))*10)} func op2(x:Int)->Int{return Int(Double(x)/150.0*100)} func op3(x:Int)->Int{return x + 3} var scores1 = [36,61,78,99] changeScores(op1 , &scores1) var scores2 = [88,101,124,137,150] changeScores(op2 , &scores2) var scores3 = [59,61,76,83,95] changeScores(op3 , &scores3) //使用系统sorted对数组降序 var arr = [Int]() for _ in 1...20{ arr.append(Int(arc4random()%100)) } sorted(arr) func compareTwoInts(a:Int,b:Int)->Bool{ return a>b//降序 } sorted(arr, compareTwoInts)//第二个参数传一个定义好降序规则的函数 ////////////////////////////part7函数式编程 //将一个函数用作另一个函数的返回值 func tier1MailFee(weight:Int)->Int{ return 1*weight; } func tier2MailFee(weight:Int)->Int{ return 2*weight; } //(Int)->Int表示返回值的类型是一个函数类型 func chooseMailFeeCalcMethod(weight:Int)->(Int)->Int{ return (weight <= 10) ? tier1MailFee : tier2MailFee } func totalPrice(price:Int,weight:Int)->Int{ let mailFeeCalc:(Int)->Int = chooseMailFeeCalcMethod(weight)//定义一个接收函数的变量 return mailFeeCalc(weight) + price * weight//4+8 } totalPrice(2, 4) totalPrice(1, 12) //函数内可嵌套函数 //func totalPrice(price:Int,weight:Int)->Int{ // func chooseMailFeeCalcMethod(weight:Int)->(Int)->Int{ // return (weight <= 10) ? tier1MailFee : tier2MailFee // } // let mailFeeCalc:(Int)->Int = chooseMailFeeCalcMethod(weight)//定义一个接收函数的变量 // return mailFeeCalc(weight) + price * weight //}
2.闭包
嵌套函数,函数定义在函数体的内部。通过闭包可以对这种嵌套函数进行简化
//嵌套函数 func getMathFunc(#type:String)-> (Int)->Int{ func squre(num:Int)->Int{ return num * num; } func cube(num:Int)->Int{ return num * num * num; } switch(type){ case "squre": return squre; default: return cube; } } var squre:(Int)->Int = getMathFunc(type: "squre"); println(squre(4));
(1)闭包的格式: {函数的声明 in 方法的实现}
{(形参列表)->返回值类型 in
执行表达式
}
(2)闭包的各种简化形式
(3)闭包可以做一个函数的参数,最后一个参数为闭包时,可以写在函数外面(结尾闭包)。其格式: func 函数名(形参列表){函数的声明 in 方法的实现}
///////////////////////////////part1闭包相当匿名函数 //闭包{(a:Int,b:Int)->Bool in return a>b} sorted(arr, { (a:Int,b:Int)->Bool in return a>b//in关键字 }) arr var strArr = ["d","cd","bcd","abcd","abc","ab","a"] strArr = sorted(strArr, { (s1:String,s2:String)->Bool in if countElements(s1) != countElements(s2){ return countElements(s1) < countElements(s2)//字母个数少的在前面 } return s1 < s2//升序 }) sorted(arr, {a,b in return a>b})//简短版 sorted(arr, {$0 > $1})//降序,$0,$1表示第一二个参数 sorted(arr, >)//操作符作函数传入,该话题后续 ///////////////////////////////part2 //结尾闭包trailing closure strArr = sorted(strArr) { (s1:String,s2:String)->Bool in if countElements(s1) != countElements(s2){ return countElements(s1) < countElements(s2)//字母个数少的在前面 } return s1 < s2//升序 } //闭包内可以访问外边变量,后续相关的内存管理 var datas = [0,1,2,3,4,5,6,7,8,9,10] var num = 3 datas = sorted(datas){ return fabs(CGFloat($0-num)) < fabs(CGFloat($1-num)) } ///////////////////////////////part3 //函数和闭包都属于引用类型,其他数据类型属于值类型 func calcTotalMiles(todayMiles:Int)->()->Int{ var totalMiles = 0//与一般函数中的变量差别很大,通常其他语言函数里定义的变量都是存放在栈区,调研函数后,定义的变量通通会销毁 return {totalMiles += todayMiles;return totalMiles}//闭包 } var dailyTwoMiles = calcTotalMiles(2) dailyTwoMiles() dailyTwoMiles() dailyTwoMiles() var myPlan = dailyTwoMiles myPlan() dailyTwoMiles()
.
//闭包的简化形式 // var squre:(Int)->Int = {(num) in return num * num } // println(squre(4)); // var squre:(Int)->Int = {num in return num * num } // println(squre(4)); //省略形参名,通过$0、$1...来引用第一个、第二个参数 var squre:(Int)->Int = {$0 * $0} println(squre(4)); // var result:Int = { var result = 1; for i in 1...$1{ result *= $0; } return result; }(4,3)//{}表示闭包 (,)表示调用 println("(result)")