美文网首页
初探 swift 之 简单闭包

初探 swift 之 简单闭包

作者: wangDavid939i | 来源:发表于2018-11-30 11:24 被阅读0次

swift 中的 “闭包” 类似于 OC中的 “block”

  • 利用上下文推断参数和返回值类型
  • 隐式返回单表达式闭包,即单表达式闭包可以省略return关键字
  • 参数名称缩写
  • 尾随(Trailing)闭包语法
// 1.三目运算符判断
func wdw1 ( a:Int,b:Int )-> Int {
    
    return a > b ? b : a
}

// 2.条件语句判断
func wdw2 ( a:Int,b:Int )-> Int {
    
    if a>b {
        return a
    }else{
        return b
    }
}
闭包基本 语法
{ (parameters) -> returnType in
      statements
}


1.1下面我们用内联闭包实现数组的升序排列,

函数的最后一个参数是闭包时 () 可以省略;

注意:此时闭包的参数和返回值类型要和函数声明相同,(Self.Generator.Element, Self.Generator.Element) -> Bool

var resultName2 = usernames.sort { (s1: String, s2: String) -> Bool in
   return s1 < s2
}
//resultName2 : ["Cc", "Lecoding", "Lves", "Wildcat"]
1.2 根据上下文推断类型(Inferring Type From Context)

上面的内联闭包书写还可以更加精简,因为sort(_:)函数需要的函数参数类型已知即:(String, String) -> Bool,

因为所有的类型都可以被正确推断,返回箭头(->)和围绕在参数周围的括号也可以被省略:

var resultName3 = usernames.sort { s1, s2 in
   return s1 > s2
}
 
//["Wildcat", "Lves", "Lecoding", "Cc"]
1.3 单表达式闭包隐式返回

单行表达式闭包可以通过省略return关键字来隐式返回单行表达式的结果

var resultName4 = usernames.sort { s1, s2 in s1 > s2 }
1.4 参数名称缩写

如果你觉得还不够精简,当然还有更加精简的:

内联闭包可以省略参数名直接用参数顺序0,1,$2调用.

var resultName5 = usernames.sort ({ $0 > $1 })
1.5 运算符函数(Operator Functions)

对于上边的排序函数,你觉得内联闭包书写是最精简了,那你就错了。

Swift的String类型定义了关于大于号(>)的字符串实现,其作为一个函数接受两个String类型的参数并返回Bool类型的值。而这正好与sort(_:)方法的第二个参数需要的函数类型相符合。


var resultName6 = usernames.sort(>)

2. 尾随闭包(Trailing Closures))

尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用:

下面先定义一个计算函数,参数为:两个整数和一个函数类型参数

func caculateTwoNumbers(num1: Int, num2: Int, CaluFunction: (Int, Int) -> Int) -> Int{
    return CaluFunction(num1, num2)
}
 
//内联闭包形式,不使用尾随闭包,求和
var numReult1 = caculateTwoNumbers(2, num2: 3,CaluFunction: {(num1: Int, num2: Int) -> Int in
    return num1 + num2
})
//5
//使用尾随闭包,求乘机
var numReult2 = caculateTwoNumbers(3, num2: 4) {  $0 * $1 }
numReult2 //7
3. 捕获值(Capturing Values)

闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。

4.闭包是引用类型(Closures Are Reference Types)

和类一样,必要也是引用类型

5. 非逃逸闭包(Nonescaping Closures)

一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。可以在参数名之前标注@noescape,用来指明这个闭包是不允许“逃逸”出这个函数的。将闭包标注@noescape能使编译器知道这个闭包的生命周期.

像刚才的数组的sort(_:)函数中的参数就定义成了非逃逸闭包,


public func sort(@noescape isOrderedBefore: (Self.Generator.Element, 
Self.Generator.Element) -> Bool) -> [Self.Generator.Element]

你可能会问什么时候会出现逃逸闭包呢?举个例子:很多启动异步操作的函数接受一个闭包参数作为 completion handler。这类函数会在异步操作开始之后立刻返回,但是闭包直到异步操作结束后才会被调用。在这种情况下,闭包需要“逃逸”出函数,因为闭包需要在函数返回之后被调用。

非逃逸闭包和逃逸闭包讲的不是执行先后顺序吧,非逃逸是指你的闭包不能在函数外单独调用,只能在函数内部调用,函数调用完成后,那个闭包也就结束了。

下面举个逃逸闭包的例子:

//声明一个存放函数的数组
var functionArray: [() -> Void] = []
//定义一个接收闭包参数的函数,如果定义非逃逸函数 func doSomething(@noescape paramClosure:() -> Void) 就会编译错误
func doSomething(paramClosure:() -> Void){
    //把参数放入数组中,用于逃逸调用
    functionArray.append(paramClosure)
 
}
//调用函数
 
doSomething({print("Hello world")})
 
doSomething({print("Hello LvesLi")})
 
//逃逸调用闭包
for closurePrama in functionArray {
 
    print("\(closurePrama)")
 
}

以上笔记只作为转载摘录 感谢!浮生若梦 原贴为
闭包 - swift - 浮生若梦

相关文章

  • 初探 swift 之 简单闭包

    swift 中的 “闭包” 类似于 OC中的 “block” 利用上下文推断参数和返回值类型 隐式返回单表达式闭包...

  • swift初探之闭包

    闭包定义:一个函数和它捕获的变量、常量环境组合起来,称为闭包。(但是好多人会把闭包表达式简称闭包,但是其实是两回事...

  • swift闭包学习

    闭包作为参数 参考 Swift学习之闭包

  • Swift-闭包

    Swift 闭包 函数 ()->() Swift 中的闭包和 Objective-C 中的 block 类似,闭包...

  • Swift闭包和函数

    函数在Swift中只是一种特殊的闭包,闭包在Swift语言中是一等公民,支持闭包嵌套和闭包传递。Swift中的闭包...

  • Swift初探(二)

    继Swift初探之后,我们来继续学习下Swift里的结构体,类,协议,闭包 结构体 两种调用结构体的方法1.调用结...

  • swift学习之路

    swift3.0.1官方文档下载链接 swift(一)简单值 swift(二)流程控制 swift(三)函数和闭包...

  • Swift 闭包 简单

    先吐槽 那些也在简书上 解释swift 闭包的人 你们他么的是猪?嘛 看到别人写好的就他妈知道复制粘贴,你们自己明...

  • swift4 闭包

    swift 闭包 闭包:swift 中 函数是闭包的一种类似于oc的闭包闭包表达式(匿名函数) -- 能够捕获上下...

  • Swift中的闭包

    在Swift中有两种闭包,逃逸闭包(@escaping)和非逃逸闭包(@nonescaping)。从Swift 3...

网友评论

      本文标题:初探 swift 之 简单闭包

      本文链接:https://www.haomeiwen.com/subject/kdiccqtx.html