(作业)利用闭包实现排序
来源:互联网 发布:键盘乐器软件 编辑:程序博客网 时间:2024/06/16 17:10
在Swift中,闭包是一个非常重要的概念,它跟java的lambda表达式类似,也跟其他语言中的闭包相差无几。
在介绍闭包前要先介绍一下Swift中的函数类型。在Swift中,函数跟普通的变量一样也是有类型这个概念的,函数的类型就是它的参数和返回值,比如下面两个函数:
func add(a: Int, b: Int) -> Int { return a + b}func sub(a: Int, b: Int) -> Int { return a - b}它们两个的类型都是(Int, Int) -> Int。所以函数是可以赋值给一个变量的,那这个变量又有什么用呢?那再看看下面这个代码:
var calFun: (Int, Int) -> Int = addprint(calFun(3,5)) //输出8calFun = subprint(calFun(3,5)) //输出-2由以上示例可知,当把函数赋值给一个变量或常量时,这个变量或常量就可以当作一个函数使用,其功能与该函数相同。
那接下来介绍一下闭包,闭包又是什么呢?简单来说,闭包就是一个自包含的函数代码块,它可以作为函数的参数和返回值来使用,其格式如下:
{ (参数) -> 返回值类型 in
代码块
} //当闭包没有参数和返回值时,需要省略in;否则必须加上in
下面通过一个作业来体验一下闭包从复杂到简单的过程:
要求:找出1到10000所有的质数,将找出的质数存入可辨数组,对数组进行正反排序并输出结果
func findPrimNumber() -> [Int] { var num = [2, 3] var flag = true var sqr = 0 for x in 4...10000 { sqr = Int(sqrt(Double(x))) for y in 2...sqr { if x % y == 0 { flag = false break } } if flag { num.append(x) } flag = true } return num} //返回1到10000中所有的质数var numbers = findPrimNumber()numbers.sort() //升序排序//降序排序/// mark: method 1: 自定义函数的闭包,将函数作为参数传递进排序函数中func descending(x: Int, y: Int) -> Bool { return x > y}numbers.sort(by: descending)/// mark: method 2: 指定参数名和类型的闭包,这个是最标准的闭包的语法numbers.sort { (x: Int, y: Int) -> Bool in return x > y}/// mark: method 3: 利用推断只指定参数名的闭包,当定义函数参数时,肯定会定义传入的闭包的类型,所以可以根据上下文推断闭包中参数的类型numbers.sort { (x, y) -> Bool in return x > y}/// mark: method 4: 利用推断省略返回值类型的闭包,同第三种方法,返回值类型也可以通过上下文推断numbers.sort { (x, y) in return x > y}/// mark: method 5: 利用推断省略参数和返回值的闭包,同第三种方法,参数类型和返回值类型都可以通过上下文推断,所以可以使用一个语法糖来表示参数,其中$0表示第一个参数,$1表示第二个参数,如果还有更多的参数,依次类推numbers.sort(by: { return $0 > $1 })/// mark: method 6: 省略return的闭包,当闭包中只有一句return语句时,可以省略returnnumbers.sort { $0 > $1 }/// mark: method 7: 传入操作符函数的闭包,在Swift中,操作符也定义为函数,所以操作符也可以作闭包使用numbers.sort(by: >)
接下来再介绍一个概念:尾随闭包。先上代码:
func add(a: Int, b: Int, op: (Int, Int) -> Int) { print(op(a,b))}add(a: 1, b: 2){ $0 + $1 } //输出3//尾随闭包的好处是当闭包内的代码过多时,看起来更简洁、美观。尾随闭包就是当闭包作为函数的最后一个参数,在调用该时可以将闭包写在函数的最后面(参数之后)。这样的好处就是当函数参数过多或者闭包中代码过多时,让代码看起来更简洁、美观。
最后再介绍一下闭包的值捕获:
先来看一段代码:
var a = 10func add() { a += 1}print(a) //输出结果为10print(a) //输出结果仍为10这个代码很容易理解,在函数外定义了一个全局的变量a,在函数中更改它的值,最后再输出。可以看到在函数外面两次输出时该变量都没有变化,也就是说。是因为该变量在函数中被改变时,改变的只是这个变量的副本,而对其本身并没有影响。
那再看一段代码:
func getIncFunc(inc: Int) -> (Int) -> Int { var mt = 10 func incFunc(v: Int) -> Int { mt += 1 return inc + v + mt } return incFunc}var incFunc1 = getIncFunc(inc: 3)print(incFunc1(10)) //输出结果为24print(incFunc1(10)) //输出结果为25incFunc1 = getIncFunc(inc: 3)print(incFunc1(10)) //输出结果为24
很多人就觉得很奇怪了,为什么三次输出,有两次为24,但怎么会有一次是25呢?原因如下:
闭包中(嵌套函数一样)是引用类型,当包含该闭包的函数在被销毁之前(引用计数大于0),该函数中被闭包使用的局部变量在调用之后会留下一个副本,该闭包会一直捕获到这个值,并在以后的调用中使用。
而在最后一个输出时结果为24,这是因为在这之前,incFunc1被重新赋值,在赋值的过程中,会先将该变量之前的值销毁,并重新开辟空间给该变量,所以之前闭包捕获的值被释放,最后的结果才是24.
阅读全文
0 0
- (作业)利用闭包实现排序
- javascript利用闭包this实现继承
- 利用闭包实现bind函数
- 排序算法包实现
- 利用Apache的commons-beanutils和commons-collections包实现Java对象的按属性排序
- 作业:C++利用栈实现的计算器
- js实现选项卡效果(利用闭包方式)
- 带有期限的作业排序java实现
- 利用实现Comparator接口排序
- 利用Python实现冒泡排序
- 利用Python实现归并排序
- 利用Python实现堆排序
- 利用Python实现选择排序
- c语言实现各种排序算法(作业:点名册排序)
- 利用enterprisedt包实现FTP的操作
- 作业排序
- (作业)Swift闭包、扩展、泛型
- Spring--超简单利用quartz实现定时作业 (转)
- 把Excel表格通过MySql Workbench导入数据库表中的使用总结
- HDU 4280 Island Transport (最大流)
- 如何从零设计结构清晰、操作友好的权限管理模块
- 生成微信二维码注意事项
- OJ 2513: 小勇学分数
- (作业)利用闭包实现排序
- Git-创建与合并分支(笔记)
- vim编辑器常用命令
- java基础解析系列(三)---HashMap
- Linux 学习之创建、删除文件和文件夹命令
- ubuntu下的Samba配置:使每个用户可以用自己的用户名和密码登录自己的home目录
- Jenkins插件获取git分支的方法
- python创建目录保存文件
- R----简述logistic回归