您的位置:首页 > 移动开发 > Swift

playSwift第五章(函数和闭包)

2015-06-14 16:28 316 查看
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)")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: