博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS - Swift Closure 闭包
阅读量:6719 次
发布时间:2019-06-25

本文共 3233 字,大约阅读时间需要 10 分钟。

1、Closure

  • 闭包在 Swift 中非常有用。通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型。有了闭包,你就可以处理很多在一些古老的语言中不能处理的事情。这是因为闭包使用的多样性,比如你可以将闭包赋值给一个变量,你也可以将闭包作为一个函数的参数,你甚至可以将闭包作为一个函数的返回值。它的强大之处可见一斑。在 Swift 的很多文档教材中都说函数是“一等公民”,起初我还不是很理解“一等公民”是什么意思,但当我理解了闭包以及它的强大功能后,我恍然大悟、茅塞顿开、醍醐灌顶。原来闭包的这些特性就是“一等公民”的特性啊!

  • 闭包是功能性自包含模块,可以在代码中被传递和使用。一段程序代码通常由常量、变量和表达式组成,然后使用一对花括号“{}” 来表示闭合并包裹着这些代码,由这对花括号包裹着的代码块就是一个闭包。Swift 中的闭包与 C 和 Objective-C 中的 Block 以及其他一些编程语言中的 lambdas 比较相似。Block 和闭包的区别只是语法的不同而已,而且闭包的可读性比较强。

  • 闭包是引用类型,无论你将函数/闭包赋值给一个常量还是变量,实际上都是在将常量/变量设置为对应函数/闭包的引用,这也意味着如果你将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包。

  • 1)在 Swift 语言中有三种闭包形式:

    • 全局函数:是一个有名字但不会捕获任何值的闭包。
    • 嵌套函数:是一个有名字并可以捕获到其封闭函数域内的值的闭包。
    • 匿名闭包:闭包表达式是一个利用轻量级语法所写的,可以捕获其上下文中变量或常量值。
  • 2)函数形式:

    func myConpare(s1:String, s2:String) -> Bool {        return s1 > s2    }    let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort(myConpare)
  • 3)一般形式:

    { (parameters参数) -> returnType返回类型 in        statements    }
    • 可以使用常量、变量、inout、可变参数、元组类型作为闭包的参数,但不能在闭包参数中设置默认值,定义返回值和函数返回值的类型相同。

    • 闭包表达式中的 in 关键字表示闭包的参数和返回值类型定义已经完成,这些参数和返回值都将在下面的闭包函数体中得到处理。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort { (s1:String, s2:String) -> Bool in        return s1 > s2    }
  • 4)参数类型隐藏形式:

    • Swift 中有类型推断的特性,所以我们可以去掉参数类型。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort { (s1, s2) -> Bool in        return s1 > s2    }
  • 5)返回值类型隐藏形式:

    • Swift 中有类型推断的特性,所以我们可以去掉返回值类型。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort { (s1, s2) in        return s1 > s2    }
  • 6)return 隐藏形式:

    • 单行表达式的闭包可以通过隐藏关键字 return 来隐式地将单行表达式的结果作为返回值。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort { (s1, s2) in        s1 > s2    }
  • 7)参数名省略形式:

    • 闭包的使用非常的灵活,我们可以省略闭包参数列表中的参数的参数类型定义,被省略的参数类型会通过闭包函数的类型进行推断。同时,我们也可以在闭包函数体中通过使用闭包的参数名简写功能,直接使用 $0、$1、$2 等名字就可以引用的闭包参数值。如果同时省略了参数名和参数类型,那么 in 关键字也必须被省略,此时闭包表达式完全由闭包函数体构成。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort {        $0 > $1    }
  • 8)trailing 闭包形式:

    • 闭包可以做其他函数的参数,而且通常都是函数的最后一个参数。但是如果作为参数的这个闭包表达式非常长,那么很有可能会影响函数调用表达式的可读性,这个时候我们就应该使用 trailing 闭包。trailing 闭包和普通闭包的不同之处在于它是一个书写在函数参数括号之外(之后)的闭包表达式,函数会自动将其作为最后一个参数调用。

    • 当函数有且仅有一个参数,并该参数是闭包时,不但可以将闭包写在 () 外,还可以省略 ()。Swift 2.2 中可以不管参数的个数完全省略 ()。

      let namesArray:Array = ["Jill", "Tim", "Chris"]    let names = namesArray.sort() {        $0 > $1    }
  • 9)闭包捕获:

    • 闭包可以在其定义的上下文中捕获常量或变量,即使定义这些常量或变量的原作用域已经不存在,仍然可以在闭包函数体内引用和修改这些常量或变量,这种机制被称为闭包捕获。在 Swift 中闭包的最简单形式是嵌套函数。嵌套函数就可以捕获其父函数的参数以及定义的常量和变量,全局函数可以捕获其上下文中的常量或变量。

      func increment(amount: Int) -> (() -> Int) {        var total = 0        func incrementAmount() -> Int {        // total 是外部函数体内的变量,这里是可以捕获到的            total += amount            return total        }        // 返回的是一个嵌套函数(闭包)        return incrementAmount    }    // 闭包是引用类型,所以 incrementByTen 声明为常量也可以修改 total    let incrementByTen = increment(10)    incrementByTen()    // return 10,incrementByTen 是一个闭包    // 这里是没有改变对 increment 的引用,所以会保存之前的值    incrementByTen()    // return 20    incrementByTen()    // return 30    let incrementByOne = increment(1)    incrementByOne()    // return 1,incrementByOne 是一个闭包    incrementByOne()    // return 2    incrementByTen()    // return 40    incrementByOne()    // return 3

转载地址:http://wrjmo.baihongyu.com/

你可能感兴趣的文章
通过腾讯地图api获取用户位置限制在指定位置区域
查看>>
Mac 生成public_key
查看>>
数轴上n个点(a0,a1,.....an),长为L的绳子最多能覆盖多少个点。
查看>>
购物车增加、减少商品时动画效果:jQuery.Fly.js插件使用方法
查看>>
0622.发送邮件基本操作
查看>>
【Kylin实战】邮件报表生成
查看>>
@Url.ActionLink 和 @Url.Action
查看>>
SSM配置
查看>>
开发过程中遇到的错误
查看>>
为XShell添加复制粘贴的功能
查看>>
transform
查看>>
【实现高可效的代理模式-Squid】
查看>>
MVC之图片验证码
查看>>
xpath中如何使用变量
查看>>
网络开发之使用Web Service和使用WCF服务
查看>>
asp.net mvc实现简单的无刷新上传图片
查看>>
介绍SAP预留函数创建搜索帮助
查看>>
Merge Two Sorted Lists
查看>>
利用php的序列化和反序列化来做简单的数据本地存储
查看>>
将生成logo图片导入到Altium Designer中
查看>>