Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性
1 数组排序
1.1 问题
本案例实现一个整型数组排序的函数,数组排序的规则由传递的规则函数决定。
1.2 方案
首先定义一个整型数组排序函数sortInts,该函数有一个整型数组类型的参数,该参数必须是输入输出参数inout,否则并不能修改数组的值。另外还有一个(Int,Int)->Bool函数类型的参数rule,该参数用于提供数组的排序规则。
然后实现函数sortInts,这里采用数组的冒泡排序算法来实现排序。
接下来实现一个数组排序的规则函数rule1,该函数是(Int,Int)->Bool类型,可以将该函数设置为sortInts函数rule1规则的默认值。
最后将一个整型数组a,传递给函数调用,就能实现数组a的排序。当然也可以自定义规则传递给函数sortInts。
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:定义整型数组排序函数sortInts
首先定义一个整型数组排序函数sortInts,该函数有一个整型数组类型的参数,该参数必须是输入输出参数inout,否则并不能修改数组的值。另外还有一个(Int,Int)->Bool函数类型的参数rule,该参数用于提供数组的排序规则,代码如下所示:
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool) {
- }
然后实现函数sortInts,这里采用数组的冒泡排序算法来实现排序,代码如下所示:
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool) {
- forvari=0;i < data.count-1;i++ {
- forvar j=0;j<data.count-i-1;j++ {
- if rule(data[j], data[j+1]) {
- swap(&data[j], &data[j+1])
- }
- }
- }
- }
步骤二:实现规则函数
sortInts函数的rule参数是一个函数类型,需要调用时进行传递,该参数用于决定数组的排序规则,可以进行自定义,也就是由程序员来根据程序需求自定义排序规则。
接下来实现一个数组排序的规则函数rule1,该函数是(Int,Int)->Bool类型,可以将该函数设置为sortInts函数rule1规则的默认值,代码如下所示:
- func rule1(a:Int,b:Int)->Bool {
- return a > b
- }
- //函数类型作为参数传递
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1) {
- forvari=0;i < data.count-1;i++ {
- forvar j=0;j<data.count-i-1;j++ {
- if rule(data[j], data[j+1]) {
- swap(&data[j], &data[j+1])
- }
- }
- }
- }
最后将一个整型数组a,传递给函数调用,使用默认规则实现数组a的排序,代码如下所示:
- var a = [1,3,2,4,9,8,5,0,6,7]
- sortInts(&a)
运行结果如图-1所示:

图-1
当然也可以自定义规则传递给函数sortInts,代码如下所示:
- //自定义排序规则
- func rule2(a:Int,b:Int)->Bool {
- return a<b
- }
- sortInts(&a, rule: rule2)
- func rule3(a:Int, b:Int)->Bool {return a%3 > b%3}
- sortInts(&a, rule: rule3)
运行结果如图-2所示:

图-2
1.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- func rule1(a:Int,b:Int)->Bool {
- return a > b
- }
- //函数类型作为参数传递
- funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1) {
- forvari=0;i < data.count-1;i++ {
- forvar j=0;j<data.count-i-1;j++ {
- if rule(data[j], data[j+1]) {
- swap(&data[j], &data[j+1])
- }
- }
- }
- }
- var a = [1,3,2,4,9,8,5,0,6,7]
- sortInts(&a)
- a
- //自定义排序规则
- func rule2(a:Int,b:Int)->Bool {
- return a<b
- }
- sortInts(&a, rule: rule2)
- func rule3(a:Int, b:Int)->Bool {return a%3 > b%3}
- sortInts(&a, rule: rule3)
2 将Int数组转换为对应的String类型的数组
2.1 问题
如果需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。本案例在Array的map方法中使用尾随闭包将一个Int类型的数组[16, 58, 510]转换为对应的String类型的数组["一六", "五八", "五一零"]。
2.2 方案
Array类型有一个map方法,唯一参数是一个闭包表达式,数组中的每一个元素调用用一次该闭包函数,并返回该元素所映射的值,具体的映射方式由闭包表达式决定。
当提供给数组闭包函数后,map方法将返回一个新的数组,数组中包含了与原数组一一对应的映射后的值。
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建字典digiNames
创建一个数字和中文名映射的字典digiNames,代码如下所示:
- letdigitNames = [
- 0: "零", 1: "一", 2: "二", 3: "三", 4: "四",5: "五", 6: "六", 7: "七", 8: "八", 9: "九"]
- let numbers = [16, 58, 510]
步骤二:调用map方法
numbers数组调用map方法,该方法需要传递一个闭包表达式用于规定映射规则,这里采用尾随闭包的形式,代码如下所示:
- numbers.map {(var number) -> String in
- var output = ""
- while number > 0 {
- //字典下标返回一个可选值
- output = digitNames[number % 10]! + output
- number /= 10
- }
- return output
- }
map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来,运行结果如图-3所示:

图-3
2.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- letdigitNames = [
- 0: "零", 1: "一", 2: "二", 3: "三", 4: "四",5: "五", 6: "六", 7: "七", 8: "八", 9: "九"]
- let numbers = [16, 58, 510]
- //map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来
- let strings = numbers.map {(var number)->String in
- var output = ""
- while number > 0 {
- output = digitNames[number%10]!+output
- number/=10
- }
- return output
- }
- strings
3 定义商品条形码的枚举
3.1 问题
假设一个仓库跟踪系统需要利用两种不同类型的条形码来跟踪商品,有些商品上标有UPC-A格式的一维码,它是由三个整型数字组成。另外其他一些商品上标有QR格式的二维码,它是一个字符串,如图-4、图-5所示:

图-4

图-5
本案例要求使用枚举来表示商品条码并设置其关联值。
3.2 方案
首先把UPC-A码作为三个整型值的元组,把QR码作为一个任字符串存储起来,那么定义一个枚举Barcode并设置器关联值。
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:定义枚举Barcode
定义一个枚举Barcode表示商品条形码,它有两个成员UPCA和QRCode,UPCA的关联值是一个包含三个整型值的元组类型,QRCode的关联值是一个String类型,代码如下所示:
- enum Barcode{
- case UPCA(Int, Int, Int)
- caseQRCode(String)
- }
枚举的定义不提供任何Int或String的实际值,只是定义而已。
步骤二:使用关联值
使用刚才定义的枚举类型Barcode创建一个新的变量productBarcode,并且赋给它两个成员的关联值,代码如下所示:
- varproductBarCode : Barcode = Barcode.UPCA(692, 530372375, 0)
- productBarCode = Barcode.QRCode("ABCDEFSFD")
不同的条形码可以使用一个switch语句来检查,代码如下所示:
- switchproductBarCode {
- case .UPCA(let(num, id, check)):
- println("这是条形码\(num)-\(id)-\(check)")
- case .QRCode(let pCode):
- println("这是二维码\(pCode)")
- }
然后调用函数,运行结果如图-6所示:

图-6
3.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- //关联值
- enum Barcode{
- case UPCA(Int, Int, Int)
- caseQRCode(String)
- }
- varproductBarCode : Barcode = Barcode.UPCA(692, 530372375, 0)
- productBarCode = Barcode.QRCode("ABCDEFSFD")
- switchproductBarCode {
- case .UPCA(let(num, id, check)):
- println("这是条形码\(num)-\(id)-\(check)")
- case .QRCode(let pCode):
- println("这是二维码\(pCode)")
- }
4 定义几何形状的结构体
4.1 问题
属性分为存储属性和计算属性,存储属性就是用常量或变量保存的属性值。计算属性的值是通过计算得出的。
按如下要求完成本案例:
1)定义一个Point结构体,用于表示点坐标(x,y);
2)定义一个Size结构体,用于表示形状的长和宽(width,height);
3)定义一个Rect结构体,用于表示有原点和尺寸的矩形,还提供一个表示中心点center的计算属性;
4)创建一个Rect类型的实例square,并设置和修改center属性移动矩形,如图-7所示:

图-7
4.2 方案
首先定义Point结构体和Size结构体,Point结构有两个存储属性x和y,用于表示点坐标。Size结构体也有两个存储属性width和height,用于表示长宽。
然后定义矩形Rect结构体,该结构体有两个存储属性一个是Point类型的origin,用于表示原点坐标,另一个是Size类型的size,用于表示矩形的长宽。
Rect结构体还有一个Point类型的计算属性center,用于表示矩形的中心点,需要提供getter和setter方法获取和设置其值。
最后创建一个Rect实例square,设置和修改center属性,查看输出结果。
4.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:定义Point和Size结构体
首先定义Point结构体和Size结构体,Point结构有两个存储属性x和y,用于表示点坐标。Size结构体也有两个存储属性width和height,用于表示长宽,代码如下所示:
- struct Point {
- //存储属性
- var x = 0.0
- var y = 0.0
- }
- struct Size {
- //存储属性
- var width = 0.0
- var height = 0.0
- }
步骤二:定义Rect结构体
然后定义矩形Rect结构体,该结构体有两个存储属性一个是Point类型的origin,用于表示原点坐标,另一个是Size类型的size,用于表示矩形的长宽,代码如下所示:
- structRect {
- //存储属性
- var origin = Point()
- var size = Size()
- }
Rect结构体还有一个Point类型的计算属性center,用于表示矩形的中心点,需要提供getter和setter方法获取和设置其值,代码如下所示:
- structRect {
- //存储属性
- var origin = Point()
- var size = Size()
- //计算属性
- varcenter:Point {
- get {
- letcenterX = origin.x + size.width/2
- letcenterY = origin.y + size.height/2
- return Point(x: centerX, y: centerY)
- }
- set(newCenter) {
- origin.x = newCenter.x - size.width/2
- origin.y = newCenter.y - size.height/2
- }
- }
- }
步骤三:创建square实例
创建一个Rect实例square,原点坐标设置为(0.0,0.0),长宽设置为(10.0,10.0),可以通过点运算调用getter方法获取到center属性的值,代码如下所示:
- var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
- letcenterSquare = square.center
可以看到center的值为(5.0,5.0),运行结果如图-8所示:

图-8
然后重新设置center的值(15,15),设置属性center的值会调用setter来修改该属性origin的值,代码如下所示:
- square.center = Point(x: 15, y: 15)
可以看到此时square的origin属性的值为(10,10),运行结果如图-9所示:

图-9
4.4 完整代码
本案例中,完整代码如下所示:
- importUIKit
- struct Point {
- //存储属性
- var x = 0.0
- var y = 0.0
- }
- struct Size {
- //存储属性
- var width = 0.0
- var height = 0.0
- }
- structRect {
- //存储属性
- var origin = Point()
- var size = Size()
- //计算属性
- varcenter:Point {
- get {
- letcenterX = origin.x + size.width/2
- letcenterY = origin.y + size.height/2
- return Point(x: centerX, y: centerY)
- }
- set(newCenter) {
- origin.x = newCenter.x - size.width/2
- origin.y = newCenter.y - size.height/2
- }
- }
- }
- var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
- letcenterSquare = square.center
- square.center = Point(x: 15, y: 15)
Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性的更多相关文章
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- 【Swift学习】Swift编程之旅---类和结构体(十三)
与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意:通常一个类 ...
- Swift语法学习之 类和结构体
类和结构体 本页包括内容: 类和结构体对照 结构体和枚举是值类型 类是引用类型 类和结构体的选择 集合(collection)类型的赋值与复制行为 与其他编程语言所不同的是,Swift 并不要求你为自 ...
- swift学习笔记之-类和结构体
//类和结构体 import UIKit //类和结构体 /* 1.枚举enum.结构体struct和String.Array.Dictionary类型,都属于值传递类型,被赋值给新的常量或变量时传递 ...
- Swift学习笔记(11)--类与结构体
类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文 ...
- Swift3.0P1 语法指南——类和结构体
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
- Swift的闭包,枚举,类和结构体
闭包(Closures) 使用过其它语言的应该对代码块并不陌生,Swift中的闭包与C,OC中的Block相似. 表示自包括的函数代码块.能够在代码中传递和使用. 而且能够捕获和存储上下文的变量以及常 ...
- 站在OC的基础上快速理解Swift的类与结构体
阅读此文章前,您已经有一定的Object-C语法基础了!) 2014年,Apple推出了Swift,最近开始应用到实际的项目中. 首先我发现在编写Swift代码的时候,经常会遇到Xcode不能提示,卡 ...
- Swift面向对象基础(上)——Swift中的类和结构体(上)
学习来自<极客学院> import Foundation //1.定义类和结构体 /* [修饰符]calss 类名{ 零到多个构造器 零到多个属性 零到多个方法 零到多个下标 } 修饰符可 ...
- swift 类 与 结构体
这两天突然有人问我 swift里面 类和 结构体 有什么区别? 说实在的本人目前不太看好swift,相信很多人也是,oc 都 很成熟了. 本人目前不打算深入了解swift的原因swift 语言 ...
随机推荐
- Chome v42 支持Java
从ver42开始,Chrome默认禁用了NPAPI.可以去chrome://flags/#enable-npapi开启,但是google很有可能在9月从代码中彻底移除NPAPIFirefox也有这个意 ...
- css实现强制不换行/自动换行/强制换行
在我们日常的编码中经常会遇到这段文字不可以换行,或者自动换行的需求.虽然这个功能在我们平时很常见但是我相信大家一定不会可以的去记住它吧(至少小月是很懒惰的从来是用什么查什么 ♦ 嘻嘻...).今天我们 ...
- Understanding the Internal Message Buffers of Storm
Understanding the Internal Message Buffers of Storm Jun 21st, 2013 Table of Contents Internal messag ...
- javascript如何用户的判断操作系统
<script> alert(window.navigator.userAgent); if(window.navigator.userAgent.indexOf("Window ...
- 114 的 dns 的解析测试
114 的 dns 号称使用 BGP Global AnyCast 技术多点部署 的方式, 可以将用户请求导向到"就近"的服务器,理论上是可以得到域名网络就近解析的IP的,所以将 ...
- Python的入门要点
一.输入 1.键盘输入 在python 2.7中,不用input(),而用 raw_input()读入一行键盘输入,并转化为字符串. s = map(int ,raw_input().split()) ...
- 【转】Linux下如何清除系统日志
使用过Windows的人都知道,在使用windows系统的过程中系统会变得越来越慢.而对于Windows下饱受诟病的各种垃圾文件都需要自己想办法删除,不然系统将会变得越来越大,越来越迟钝!window ...
- oracle 用户创建这个挺靠谱
CREATE TEMPORARY TABLESPACE test_tempTEMPFILE 'C:\oracle\product\10.1.0\oradata\orcl\test_temp01.dbf ...
- spring知识
Spring以IoC.AOP问主要思想,鞥协同struts,hibernate,webwork,jsf,iBatis等框架. Spring最主要的思想史IoC(Inversion of Control ...
- SQL Server 2005中的CTE递归查询得到一棵树
感觉这个CTE递归查询蛮好用的,先举个例子: use City; go create table Tree ( ID int identity(1,1) primary key not null, N ...