Swift4.0中的闭包介绍

闭包英文名叫closure , 在swift开发项目中随处可见, 它的本质和函数差不多,但是却比函数使用方便,因为swift中可以通过上下文识别传入的值,我们就不用像使用函数一样把全部的值都定义一边!当一个函数返回值或着参数需要传入一段逻辑运算或操作,就可以考虑去使用闭包,在OC语言中我们称之为block ,在Java语言中我们称之为Lamdba,这种调用函数的方法,也叫做函数式编程

下面看一个闭包使用的例子 创建一个数组 并用.sorted函数按照用户传入的排序逻辑排序

var num : [Int] = [1,34,5,7,88,8,5]

//可以看到系统要我们传入的是 两个Int参数 并返回一个Bool值 

num.sorted(by: <#T##(Int, Int) throws -> Bool#>)

//我们把这段排序逻辑写成函数形式  a>b返回true 就是说a大的话就排前面

num.sorted(by: { (a : Int,b : Int) -> Bool in a>b })

排序后结果为[88, 34, 8, 7, 5, 5, 1] ,sort函数系统默认是从小到大排序的

当然既然传入的是一个函数 系统自带的+ - * /这些都是操作函数 

num.sorted(by: >)

这样得到的结果也一样 从大到小排序

 

下面我们看一下三个著名的函数式编程式 他们都是系统对象自带的函数 

//函数式编程的著名公式
//map函数  Int -> Any 
//假定数组里面的是一个班的成绩 我们把低于60分的数据转成字符串"不及格" 反则是"及格"
//把原来装着Int的数组改变成一个装着字符串的数组 
//当然你也可以转成Bool 或者把Int都转成二进制 
func TransformMethod1(score:Int) ->String{
    return score<60 ? "不及格": "及格"
}
//传入函数
num.map(TransformMethod1)
//传入闭包
num.map({ (score)-> String in
    score>60 ? "及格":"不及格"
})

//filter函数
//过滤去不要的信息 比如拿到分数里面高于80分的学生数组
func getScoreOverEighty(score:Int) ->Bool{
    return score>80
}
//传入函数
num.filter(getScoreOverEighty)
//传入闭包
num.filter({a in return a>80})

//reduce函数
// 一般用于求数组中所有数的和
func reduceMethod(a : Int ,b : Int)->Int{
   return a+b
}
//传入函数
num.reduce(0, reduceMethod)
//传入闭包
num.reduce(0, {a,b in a+b})

 

闭包的结尾式写法 当闭包作为函数最后一个参数的时候 可以把闭包放在括号外面 可以让人更加清晰的读出这个闭包的逻辑


let num : [Int] = [1,2,3,4,5,6,7]
//设置一个闭包 把所有数转化成二进制
//这里不知道要返回哪个值 所以需要声明返回值
num.map(){(number)->String in
    var number = number
    var result = ""
    repeat{
        result = String(number%2) + result
        number /= 2
    }while number != 0
    return result
}

//返回后的数组值 ["1", "10", "11", "100", "101", "110", "111"]
//当然map函数没有改变原数组

开发IOS人员经常接触的结尾式写法 就是UIView里面的动画执行了 括号放在外面 我们就可以更专注于逻辑的实现而不是该方法的参数是什么

//执行时间3秒钟
UIView.animate(withDuration: 3.0) {
    sonV.backgroundColor = UIColor.white
    sonV.frame = fatherV.frame
}

闭包的更多用法-闭包作为返回值  当然都是涉及函数式编程思想

下面是函数做为返回值的写法 

import UIKit
//设置两个函数 计算自助餐中剩余食物的收费计算方法
//不用额外收费
func chargeMethod1(left:Int)->Int{
    return 0
}
//超出10单位的剩余食物每单位加收15的费用
func chargeMethod2(left:Int)->Int{
    return (left-10)*15
}
func chargeForResidualFoodInBuffet(_ left:Int,_ orignalPrice:Int) ->Int{
    //把该接口隐藏
    //如果剩余食物少于10个单位 就采用第一种收费方式 否则就采用第二种
    func chooseChargeMethodByResidualFood(_ left :Int) -> (Int)->Int{
        return left<10 ? chargeMethod1:chargeMethod2
    }
   
    //得到计算的方法
    let method = chooseChargeMethodByResidualFood(left)
    //返回 剩余食物价钱+原价
    return method(left)+orignalPrice
}

下面是闭包代替函数的写法 代码量更少了

import UIKit

func chargeForResidualFoodInBuffet(_ left:Int,_ orignalPrice:Int) ->Int{
    //把该接口隐藏
    func chooseChargeMethodByResidualFood(_ left :Int) -> (Int)->Int{
        //闭包式写法
        //由于少于10的时候不收取费用 所以我们不需要拿到参数 _代替 
        return left<10 ? { _ in return 0} : { a in return (a-10)*15 }
    }
    //得到计算的方法
    let method = chooseChargeMethodByResidualFood(left)
    
    return method(left)+orignalPrice
}

 

注意⚠️ 闭包和函数都是引用类型的 不是值类型

import UIKit

//使用函数返回值
func eat( food:Int) -> ()->Int
{
    var totalCarolias = 0
    func PersonalEnergy() ->Int {
        totalCarolias = food + totalCarolias
        return totalCarolias
    }
    return PersonalEnergy
}
//使用闭包返回值
func eat1( food:Int) -> ()->Int
{
    var totalCarolias = 0

    return {
        totalCarolias = food + totalCarolias
       return totalCarolias
    }
}
//闭包其为引用类型 所以totalCarolias开辟了一片存储空间 随闭包的调用而改变
//peopleA 加上()表明调用函数
let peopleA = eat(food: 500)
peopleA() //500
peopleA() //1000
peopleA() //1500

let peopleB = eat1(food: 600)
peopleB() //600
peopleB() //1200
peopleB() //1800

这里eat(food : )每调用一次也会会开辟一个新的空间 这时候才会创建一个新的totalCarolias

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值