当前位置: 首页 > 编程日记 > 正文

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,该参数用于提供数组的排序规则,代码如下所示:

  1. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool{
  2. }

然后实现函数sortInts,这里采用数组的冒泡排序算法来实现排序,代码如下所示:

  1. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool{
  2. forvari=0;i < data.count-1;i++ {
  3. forvar j=0;j<data.count-i-1;j++ {
  4. if rule(data[j], data[j+1]) {
  5. swap(&data[j], &data[j+1])
  6. }
  7. }
  8. }
  9. }

步骤二:实现规则函数

sortInts函数的rule参数是一个函数类型,需要调用时进行传递,该参数用于决定数组的排序规则,可以进行自定义,也就是由程序员来根据程序需求自定义排序规则。

接下来实现一个数组排序的规则函数rule1,该函数是(Int,Int)->Bool类型,可以将该函数设置为sortInts函数rule1规则的默认值,代码如下所示:

  1. func rule1(a:Int,b:Int)->Bool {
  2. return a > b
  3. }
  4. //函数类型作为参数传递
  5. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1{
  6. forvari=0;i < data.count-1;i++ {
  7. forvar j=0;j<data.count-i-1;j++ {
  8. if rule(data[j], data[j+1]) {
  9. swap(&data[j], &data[j+1])
  10. }
  11. }
  12. }
  13. }

最后将一个整型数组a,传递给函数调用,使用默认规则实现数组a的排序,代码如下所示:

  1. var a [1,3,2,4,9,8,5,0,6,7]
  2. sortInts(&a)

运行结果如图-1所示:

图-1

当然也可以自定义规则传递给函数sortInts,代码如下所示:

  1. //自定义排序规则
  2. func rule2(a:Int,b:Int)->Bool {
  3. return a<b
  4. }
  5. sortInts(&a, rule: rule2)
  6. func rule3(a:Int, b:Int)->Bool {return a%> b%3}
  7. sortInts(&a, rule: rule3)

运行结果如图-2所示:

图-2

1.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. func rule1(a:Int,b:Int)->Bool {
  3. return a > b
  4. }
  5. //函数类型作为参数传递
  6. funcsortInts(inout data:[Int],rule:(Int,Int)->Bool = rule1{
  7. forvari=0;i < data.count-1;i++ {
  8. forvar j=0;j<data.count-i-1;j++ {
  9. if rule(data[j], data[j+1]) {
  10. swap(&data[j], &data[j+1])
  11. }
  12. }
  13. }
  14. }
  15. var a [1,3,2,4,9,8,5,0,6,7]
  16. sortInts(&a)
  17. a
  18. //自定义排序规则
  19. func rule2(a:Int,b:Int)->Bool {
  20. return a<b
  21. }
  22. sortInts(&a, rule: rule2)
  23. func rule3(a:Int, b:Int)->Bool {return a%> b%3}
  24. 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,代码如下所示:

  1. letdigitNames [
  2. 0"零"1"一"2"二"3"三"4"四",5"五"6"六"7"七"8"八"9"九"]
  3. let numbers [1658510]

步骤二:调用map方法

numbers数组调用map方法,该方法需要传递一个闭包表达式用于规定映射规则,这里采用尾随闭包的形式,代码如下所示:

  1. numbers.map {(var number-> String in
  2. var output ""
  3. while number {
  4. //字典下标返回一个可选值
  5. output = digitNames[number 10]! + output
  6. number /= 10
  7. }
  8. return output
  9. }

map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来,运行结果如图-3所示:

图-3

2.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. letdigitNames [
  3. 0"零"1"一"2"二"3"三"4"四",5"五"6"六"7"七"8"八"9"九"]
  4. let numbers [1658510]
  5. //map函数是数组的方法,可以迭代数组中每一元素传入闭包执行一次,并将执行后的结果做成一个数组返回回来
  6. let strings = numbers.map {(var number)->String in
  7. var output ""
  8. while number {
  9. output = digitNames[number%10]!+output
  10. number/=10
  11. }
  12. return output
  13. }
  14. 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类型,代码如下所示:

  1. enum Barcode{
  2. case UPCA(Int, Int, Int)
  3. caseQRCode(String)
  4. }

枚举的定义不提供任何Int或String的实际值,只是定义而已。

步骤二:使用关联值

使用刚才定义的枚举类型Barcode创建一个新的变量productBarcode,并且赋给它两个成员的关联值,代码如下所示:

  1. varproductBarCode : Barcode = Barcode.UPCA(6925303723750)
  2. productBarCode = Barcode.QRCode("ABCDEFSFD")

不同的条形码可以使用一个switch语句来检查,代码如下所示:

  1. switchproductBarCode {
  2. case .UPCA(let(num, id, check)):
  3. println("这是条形码\(num)-\(id)-\(check)")
  4. case .QRCode(let pCode):
  5. println("这是二维码\(pCode)")
  6. }

然后调用函数,运行结果如图-6所示:

图-6

3.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. //关联值
  3. enum Barcode{
  4. case UPCA(Int, Int, Int)
  5. caseQRCode(String)
  6. }
  7. varproductBarCode : Barcode = Barcode.UPCA(6925303723750)
  8. productBarCode = Barcode.QRCode("ABCDEFSFD")
  9. switchproductBarCode {
  10. case .UPCA(let(num, id, check)):
  11. println("这是条形码\(num)-\(id)-\(check)")
  12. case .QRCode(let pCode):
  13. println("这是二维码\(pCode)")
  14. }
 

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,用于表示长宽,代码如下所示:

  1. struct Point {
  2. //存储属性
  3. var x 0.0
  4. var y 0.0
  5. }
  6. struct Size {
  7. //存储属性
  8. var width 0.0
  9. var height 0.0
  10. }

步骤二:定义Rect结构体

然后定义矩形Rect结构体,该结构体有两个存储属性一个是Point类型的origin,用于表示原点坐标,另一个是Size类型的size,用于表示矩形的长宽,代码如下所示:

  1. structRect {
  2. //存储属性
  3. var origin Point()
  4. var size Size()
  5. }

Rect结构体还有一个Point类型的计算属性center,用于表示矩形的中心点,需要提供getter和setter方法获取和设置其值,代码如下所示:

  1. structRect {
  2. //存储属性
  3. var origin Point()
  4. var size Size()
  5. //计算属性
  6. varcenter:Point {
  7. get {
  8. letcenterX = origin.x + size.width/2
  9. letcenterY = origin.y + size.height/2
  10. return Point(x: centerX, y: centerY)
  11. }
  12. set(newCenter{
  13. origin.x = newCenter.x - size.width/2
  14. origin.y = newCenter.y - size.height/2
  15. }
  16. }
  17. }

步骤三:创建square实例

创建一个Rect实例square,原点坐标设置为(0.0,0.0),长宽设置为(10.0,10.0),可以通过点运算调用getter方法获取到center属性的值,代码如下所示:

  1. var square Rect(originPoint(x0.0, y0.0), sizeSize(width10.0, height10.0))
  2. letcenterSquare = square.center

可以看到center的值为(5.0,5.0),运行结果如图-8所示:

图-8

然后重新设置center的值(15,15),设置属性center的值会调用setter来修改该属性origin的值,代码如下所示:

  1. square.center Point(x15, y15)

可以看到此时square的origin属性的值为(10,10),运行结果如图-9所示:

图-9

4.4 完整代码

本案例中,完整代码如下所示:

  1. importUIKit
  2. struct Point {
  3. //存储属性
  4. var x 0.0
  5. var y 0.0
  6. }
  7. struct Size {
  8. //存储属性
  9. var width 0.0
  10. var height 0.0
  11. }
  12. structRect {
  13. //存储属性
  14. var origin Point()
  15. var size Size()
  16. //计算属性
  17. varcenter:Point {
  18. get {
  19. letcenterX = origin.x + size.width/2
  20. letcenterY = origin.y + size.height/2
  21. return Point(x: centerX, y: centerY)
  22. }
  23. set(newCenter{
  24. origin.x = newCenter.x - size.width/2
  25. origin.y = newCenter.y - size.height/2
  26. }
  27. }
  28. }
  29. var square Rect(originPoint(x0.0, y0.0), sizeSize(width10.0, height10.0))
  30. letcenterSquare = square.center
  31. square.center Point(x15, y15)

转载于:https://www.cnblogs.com/hytx/p/5053776.html

相关文章:

shell命令之---Linux文件权限

本章内容  理解Linux的安全性 解读文件权限 使用Linux组 1、Linux的安全性---/etc/passwd文件 # cat /etc/passwdroot:x:0:0:root:/root:/bin/bash/etc/passwd文件的字段包含了如下信息&#xff1a; 登录用户名 用户密码 用户账户的UID&#xff08;数字形式&#x…

失败原因_解析干洗店失败原因

在市面上我们其实也知道有的店面开张时间不长或者最终没有存活下来&#xff0c;干洗店也不例外。我们在看到各地干洗店的高额利润的同时&#xff0c;也会发现一些失败的干洗店。他们的干洗店为何难以运营下去呢?下面伊斯曼小编来在多个方面剖析一下其中的蹊跷和缘由&#xff1…

seg:NLP之正向最大匹配分词

已迁移到我新博客,阅读体验更佳seg:NLP之正向最大匹配分词 完整代码实现放在我的github上:click me 一、任务要求 实现一个基于词典与规则的汉语自动分词系统。二、技术路线 采用正向最大匹配(FMM)方法对输入的中文语句进行分词&#xff0c;具体的实现可以分为下面几个步骤&…

喷涂机器人保养应该注意的七个事项

喷涂机器人又叫喷漆机器人(spray painting robot)&#xff0c; 是可进行自动喷漆或喷涂其他涂料的工业机器人。目前市面上采用比较多的品牌有ABB、库卡、发那科等等&#xff0c;长时间的使用能加速工业机器人的老化&#xff0c;保养是延缓机器人老化的一大关键&#xff0c;那么…

K均值与C均值区别

k均值聚类&#xff1a;---------一种硬聚类算法&#xff0c;隶属度只有两个取值0或1&#xff0c;提出的基本根据是“类内误差平方和最小化”准则&#xff1b;  模糊的c均值聚类算法&#xff1a;-------- 一种模糊聚类算法&#xff0c;是k均值聚类算法的推广形式&#xff0c;隶…

中超赛程来100wan点in_不干了:中超球队改名“硬重启”,球迷组织绝望解散

聚焦中超和CBA&#xff0c;独一无二球迷媒体点击右上角关注&#xff0c;你不会后悔的...2021赛季中超注定会与众不同&#xff0c;足协的新规将陆续实施&#xff0c;如果降薪还在外界意料之中的话&#xff0c;那么更改中性化名字的要求则让多数俱乐部较为头疼&#xff0c;尤其是…

微博polg什么意思_贾磊:广东发微博给CBA造成了负面影响 方硕的意思可能没表达清楚...

直播吧11月5日讯 近日做客一档节目时&#xff0c;著名篮球记者贾磊谈到了前天晚上的京粤大战。贾磊谈到了王骁辉伸腿绊倒威姆斯一事&#xff1a;“我觉得这场比赛&#xff0c;王骁辉的这个动作&#xff0c;大家都看的非常清楚&#xff0c;确实是一个犯规&#xff0c;也给威姆斯…

iOS 中的网络请求 (同步请求、异步请求、GET请求、POST请求)

1、同步请求可以从因特网请求数据&#xff0c;一旦发送同步请求&#xff0c;程序将停止用户交互&#xff0c;直至服务器返回数据完成&#xff0c;才可以进行下一步操作&#xff0c; 2、异步请求不会阻塞主线程&#xff0c;而会建立一个新的线程来操作&#xff0c;用户发出异步请…

springboot 头像上传 文件流保存 文件流返回浏览器查看 区分操作系统 windows 7 or linux...

1 //我的会员中心 头像上传接口2 /*windows 调试*/3 Value("${appImg.location}")4 private String winPathPic;5 /*linux 使用*/6 Value("${img.location}")7 private String linuxPathPic;8 9 PostMapping(value "/file")10 public String f…

个人所得税计算器2016 by Jacksile

个人所得税计算器2016 个人所得税计算器2016 税前薪资&#xff1a;元各项社会保险费&#xff1a;元起征点&#xff1a;35004800元应缴税款&#xff1a;元实发薪资&#xff1a;元个人所得税计算公式 应纳税额 应纳税所得额 x 税率 &#xff0d; 速算扣除数 应纳税所得额 工资收…

interface IEngineControl封装引擎通用操作

using System; using System.Collections.Generic; using System.Text; using System.Linq; namespace SIAT {namespace Engine{/******************************************************************** 引擎控制接口&#xff0c;该类封装一些引擎中通用的操作* * ***********…

iOS 导航栏遮挡问题 --- iOS开发系列 ---项目中成长的知识七

不知大家有没有遇见过自己写的tableview被导航栏遮挡住的问题,反正我是遇见过! 因为在ios7以后所有的UIViewController创建后默认就是full Screen的&#xff0c;因此如果带导航栏的应用界面中的部分控件会被导航栏覆盖掉。 解决方案&#xff1a;可以使用ios7中的UIViewControll…

程序员笔记|如何编写优雅的Dockerfile

导读 Kubernetes要从容器化开始&#xff0c;而容器又需要从Dockerfile开始&#xff0c;本文将介绍如何写出一个优雅的Dockerfile文件。 文章主要内容包括&#xff1a; Docker容器 Dockerfile 使用多阶构建感谢公司提供大量机器资源及时间让我们可以实践&#xff0c;感谢在此专…

Oracle面试问题汇总

1:SqL 优化 1&#xff1a;尽量避免使用 select * 查询方式 因为oracle 在解析过程中 会将*依次转化成所以的列名。 2&#xff1a;减小访问数据库的次数 因为每执行一条sql语句的时候&#xff0c;oracle内部会做许多的事情 如&#xff1a;解析sql &#xff0c;估算索引的利用效率…

相关性分析p值_一行代码掌握皮尔逊相关分析,洞察变量关系

变量类型与推荐的假设检验方法可以看到&#xff0c;当我们探索两个连续变量之间的关系时&#xff0c;相关分析是一个很好的选择。那么&#xff0c;相关分析的原理是什么&#xff1f;如何在Python中实现相关分析呢&#xff1f;一、Pearson相关系数针对两个独立的服从正态分布的连…

润前报表简单问题

Q&#xff1a;设计器如何打开A&#xff1a;如果是安装的&#xff0c;那么直接到菜单下&#xff0c;打开润乾报表设计器就行了&#xff0c;如果是压缩包或者从别人那儿拷过来的&#xff0c;就运行\reportHome\bin下面的startup.bat就可以打开了。 Q&#xff1a;做一个报表最基本…

一个简单的slider滑块组件

2019独角兽企业重金招聘Python工程师标准>>> 我们先来看一张图片&#xff1a; 要实现这样的效果我们有很多种方法&#xff0c;比如直接使用<input type"range" />修改样式即可&#xff0c;也可用下面的这种方式修改 样式 HTML代码&#xff1a; <…

压测接口线程数设置_ZAT掌门性能压测巡检系统实战和落地

项目背景随着业务拓展&#xff0c;对于接口性能的要求也在上升&#xff0c;各部门也开始针对部分慢接口进行优化&#xff0c;从测试角度针对这些优化需求进行测试时不仅要保证对应接口的功能正常使用同时也要验证接口优化成果。在日常的开发工作中一些后台服务配置的改动也会对…

01python语言程序设计基础——初识python

1.python的字符串中format函数用法 format 函数可以接受不限个参数&#xff0c;位置可以不按顺序。In [2]:"{} {}".format("hello", "world") # 不设置指定位置&#xff0c;按默认顺序Out[2]:hello world In [3]:"{0} {1}".format(&q…

没有什么不可能(1)

近在读一本书《没有什么不可能》&#xff0c;书中宗旨就是&#xff1a;这个世界没有什么不可能&#xff0c;每个人的脚下都有一条通往成功的道路&#xff0c;信念是一切力量的源泉。这本书看了三分之一&#xff0c;跟大家分享一下前三个观点。 1、只有想不到&#xff0c;没有做…

浅浅认识之VBS脚本访问接口与COMODO拦截COM接口

这2天测试了一个使用了WMI提供ASEC后门&#xff0c;里面使用了JS脚本往外请求http获取执行命令。但我的分析系统却没抓到这个行为&#xff0c;可在真机中确实抓到有HTTP请求。相当奇怪。 最后无奈windbg出手&#xff0c;内核断点afd 发送函数。最后发现是scrcons.exe进程&#…

redis最大储存512m_redis系列篇01

今天写的这篇是redis系列的文章&#xff0c;我的安排是由浅入深写redis系列。本篇是简单的介绍入门&#xff0c;后续的文章会详细讲解redis深层次的知识。欢迎大家关注我的微信公众号&#xff1a;码农Bug首先说几个简单的命令&#xff1a;keys *:查询所有的键值del key&#xf…

批处理命令——goto 和 :

谈起goto&#xff0c;相信大家应该想到的是面向过程编程。其实&#xff0c;这就相当于当有人向你谈起class&#xff0c;意味着你就懂得面向对象编程。如果你不懂&#xff0c;那么你们的沟通将会很困难。不懂我说的啥意思吗&#xff1f;请参见曾经分享王路的一篇文章《永远不要对…

浮动布局会受父框滚动条影响

此时的效果是&#xff1a;如果此时把父框的滚动条去掉或隐藏掉&#xff1a;而此时的效果是:总结:1 有时我们的布局发生了改变可能就是受到出现滚动条的影响了 而我们很容易忽略掉这一点转载于:https://blog.51cto.com/11871779/2387118

Delphi7的主窗口

Delphi7的主窗口转载于:https://www.cnblogs.com/LoveFishC/archive/2012/08/10/3845692.html

线程组多次调用_详细分析 Java 中启动线程的正确和错误方式

start 方法和 run 方法的比较代码演示:/** * * start() 和 run() 的比较 * * * author 踏雪彡寻梅 * version 1.0 * date 2020/9/20 - 16:15 * since JDK1.8 */public class StartAndRunMethod {public static void main(String[] args) {// run 方法演示// 输出: name: main//…

Concurrency Runtime in Visual C++ 2010

PDC 2010 Hejlsberg的演讲中我们看到了VB.NET、C#新的简化异步编程的方式&#xff08;可以下载新的Async CTP体验&#xff09;。之前的TPL&#xff08;Task Parallel Library&#xff09;简化了并行编程。工业语言的飞速发展大大改进、简化了开发人员的编程方式。不仅是微软平台…

关于安卓你不知道的6件事

安卓第一次亮相是出如今2008年公布的HTC Dream手机上&#xff0c;到如今为止它已经6岁了。或许没有人想过在2010年底它就成为了智能手机平台率先的操作系统。这当然要感谢谷歌的努力和强大的財力支持。尽管眼下安卓系统是世界上最流行的移动操作系统&#xff0c;可是关于它的非…

vmware的三种网络模式讲解

vmware有三种网络设置模式&#xff0c;分别是Bridged(桥接),NAT(网络地址转换)&#xff0c;Host-only(私有网络共享主机) 1.Bridged(桥接) 桥接模式默认使用的是&#xff1a;VMnet0 什么是桥接模式&#xff1f;桥接模式就是把主机网卡和虚拟机虚拟的网卡利用虚拟网桥进行通信。…

当前路径_[JSP] 07 JSP 路径问题

首先先明确一下下列URL的假设一个URL是这样的losthost:8080/myservlet/path服务器根路径:losthost:8080/项目根路径:losthost:8080/myservlet/明确了服务器根路径和项目根路径之后,我们就可以开始学习后面的知识了servlet路径问题请求转发和重定向的相对路径写法总结:Servlet重…