Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值。在使用数组时,一个常见的致命错误就是数组越界。如果在你的应用程序中数组越界了,那么对不起,如果由着程序的性子的话是会崩溃的。为了防止崩溃呢,我们会对集合做一些安全的处理。比如对数组进行扩展,从而对数组的索引进行安全检查,保证数组的index在正常范围内。在Objective-C中也是经常对数组,字典等做一些处理操作。

  今天的博客的主要内容是先对Objective-C中常用集合的安全扩展进行介绍,由此在窥探一下Swift语言中的处理。并且还会介绍Swift中自定义下标,说白了自定义下标其实就是通过下标的形式与特定的下标值来访问一个对象。自定义下标在有些场合中是非常实用的。然后下方还会给出数组切片的概念与实用方式。废话少说进入今天的主题。

一、安全的索引集合元素

  对一个集合索引进行安全检查是很有必要的,也是经常实用的,最常见的就是对数组和字典索引的安全检查,该部分内容就是类比这Objective-C中的数组索引的安全检查来扩充Swift的数组,从而让你的Swift数组也同样具备对数组安全检查的功能。

  1. Objective-C中NSArray对索引的安全扩展

  下方这段代码是非常简单的,它是对Objective-C中的NSArray做的扩展,该方法位于NSArray相关的延展中。在你的项目中,如果添加了此段延展代码,那么你就可以通过objectAtIndexSafe:方法对数组进行安全的索引。有代码不难看出在定义该函数参数时,我们将index声明为NSUInteger,也就是正整数,这就排除了你对下标传入一个负数。紧接着又对index的合法性进行验证,如果index不在数组有效范围内,那么就返回nil。当你查找的元素不存在时,你返回nil是不会造成程序崩溃的,因为nil的地址是0x0, 这和归零若引用有些类似。

  当然下方只是NSArray安全扩展其中一个方法,还有许多扩展的安全方法,比如数组的增删改查都可以进行相应的安全扩展,扩展的方式和思路与下方这段简单代码类似,再次就不花过多的篇幅对其进行介绍了。

- (id)objectAtIndexSafe:(NSUInteger)index {if (index > self.count-1) {return nil;}return [self objectAtIndex:index];
}

  2.Swift中对Array的安全扩展

  上面简单的对Objective-C中的安全方法进行了简单的介绍,就算是对Swift相关内容的引子吧,下方将会给出Swift语言中类似的方法。对Swift相关方法介绍时,我会尽量的详细一些,因为毕竟本篇博客主要是关于Swift内容的。接下来将对上面Objective-C中NSArray数组索引安全验证的方法使用Swift语言进行重新。当然重写的内容也是非常容易理解的。

    (1)主要是对subscript方法进行重载,在重载的subscript方法中,对index的范围通过三目运算符进行了安全检查。如果index在0..<count这个半开区间内,那么就返回当前索引的值,如果不在该范围内就返回nil, 下方就是对Array索引的安全检查。

extension Array {subscript (safe index: Int) -> Element? {return (0..<count).contains(index) ? self[index] : nil}
}

    

    (2)上面是对Swift中的Array进行了安全索引扩展,接下来就是简单的使用了,下方的代码段是对上面安全扩展函数的测试。首先创建了一个数组testArray, 然后创建了一个索引数组indexs, 然后遍历indexs中的元素值,将其作为testArray的下标,对testArray进行检索。当然检索时,使用的是我们上面定义的safe方法,并且在indexs下标数组中存在非法的下标。在这种情况下,我们来验证一下我们的安全方法。

    当然在数组遍历中,我们使用了for-in循环取出indexs中的每个index, 然后使用guard语句取出testArray中的值。使用guard语句能很好的过滤掉因为非法的index而返回的nil值。具体代码段如下所示:

    上面的代码段理解起来并不难,上述测试代码的运行结果如下所示,从运行结果可以很好的说明问题,并且在index非法时不会崩溃,并合理的给出相应的错误提示,请看下方具体运行结果。

    上面的延展也可以通过对整个集合类型,也就是CollectionType进行扩展,不过在扩展CollectionType时要对Index使用where子句进行限制,使Index必须符合Comparable协议,具体实现如下所示,不过下面的方法比较少用,因为一般是数组存在越界的情况,因为在字典中,如果你对一个不存在的键进行值的索引,会返回nil值,而不会崩溃。但是在数组中,你对不存在的index进行索引,就会抛出错误。下方是另一种处理方式,不过该方式用的比较少。

    实现下方延展后,同样可以在数组中使用safe方法。

 

  

二、使用多个索引下标的数组

  延展的功能是非常强大的,该部分将会给出另一个数组的延展。该延展的功能是可以通过多个索引给数组设置值,以及通过多个索引一次性获取多个数组的值。该功能是非常强大的,接下来将一步步实现该功能。

  1. 了解zip()函数以及Zip2Sequence

    在实现数组多个索引扩展时,需要使用到zip()函数,zip()函数接收两个序列,并且返回一个Zip2Sequence类型的数据。zip()函数究竟是干嘛的呢?接下来将会通过一个小的实例来搞一下zip()函数。首先看一下Apple的帮助文档上对zip()函数的介绍。具体如下所示:

     上面那句英文的意思大概就是“基于两个基本序列构建了一个序列对,在序列对中,第i对,代表着每个基本序列中的第i个元素。”在zip函数定义的过程中,我们可以看到,zip()是一个泛型函数,其接收两个SequenceType类型的参数,然后返回一个Zip2Sequence类型的数据。新创建的序列对就存在于Zip2Sequence中。说这么多还是来个小Demo实惠一些,通过一个小实例,看zip()函数的用法一目了然。

    (1) 创建两个数组zip1和zip2, 将这两个数组作为zip()函数的参数,将两个数组进行合并。具体实现如下:

    (2) 通过上面的程序可以看出,zipSum是一个Zip2Sequence<Array<Int>, Array<Int>>类型的常量,我们可以使用dump()对zipSum常量进行打印,观察其中的数据存储结构,具体结构如下所示:

 

    输出结果如下,由结果容易看出,在序列中有两个元素,第一个元素对应着数组zip1, 第二个元素对应着数组zip2。 

 

    (3)接下来就是对zipSum这个序列通过for-in循环进行遍历,下方就是对zipSum进行遍历的代码。

      上面对zipSum遍历的结果如下所示,由下方输出结果可知,输出是成对遍历的,如果某个数组中的元素是多余的,那么就会被忽略掉。

 

  2. 数组多个索引的延展实现

    在这个将要实现的延展中,我们对Array进行了扩展,在延展中对subscript方法进行重载,使其可以接受多个下标,并且对多个下标对应的值进行索引,并把索引结果组成数组。在subscript方法中通过get方法获取索引相应的值,通过set方法为相应的索引值进行设置。下方代码段就是该延展的实现:    

extension Array {subscript(i1: Int, i2: Int, rest: Int...) -> [Element] {//通过实现get方法,获取数组中相应的值get {var result: [Element] = [self[i1], self[i2]]for index in rest {result.append(self[index])}return result}//通过set方法,对数组相应的索引进行设置set (values) {for (index, value) in zip([i1, i2] + rest, values) {self[index] = value}}}
}

 

    在上述延展的实现中,并没有多少困难的地方。在subs两个cript函数中,使用的是可变参数,subscript函数参数的个数是两个以上(包括两个)。然后就是通过zip()函数以及对zip()函数返回的结果集进行遍历,从而对多个下标索引进行值的设置。经过上述延展,我们就可以通过多个索引对数组进行操作了。上述延展的使用方式如下: 

 

三、数组切片

  数组切片在OC中也是不存在的,是Swift新引入的概念,该部分将会对数组切片进行讨论,研究一下数组切片的使用方式及其特点。下方先通过一个小Demo来看一下如何生成数组切片。下方代码段先将一个字符串通过map函数转换成一个数组arrayTest, 然后我们创建一个该数组的切片。下方代码段创建了arrayTest数组中的下标3到下标6这个范围区间中的切片,arraySlices就是数组切片变量,它是ArraySlice<String>类型的,具体代码段如下所示。

 

  在数组切片中有一点需要注意,数组切片的下标与原始数组中的下标保持一致。如果要取出切片arraySlices中的第一个值,我们要使用arraySlices[3], 而不是arraySlices[0], 如果使用arraySlices[0]就会报错,如下所示:

  

  因为数组是值类型,尽管切片与原数组有着对应的数组下标,但是切片是原始数组的部分拷贝,所以修改切片或者修改原数组,两者互不影响,下方示例给出了该测试,如下所示:

   

  如果把切片转换成枚举,那么切片中与原始数组对应的下标关系将不存在,下方是将切片转换成枚举序列,然后对其进行遍历,代码如下:

  上述代码段输出结果如下:

    今天博客就先写到这儿,关于数组的延展还有许多,以后有机会再讨论。其实我们还可以通过一些方式来为我们自己的对象添加下标。也就是可以通过下标来访问对象属性,这个以后在讨论吧。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/458841.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/458841.shtml
英文地址,请注明出处:http://en.pswp.cn/news/458841.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大小端模式的快速判断方法

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 大小端的问题剖析&#xff1a; 嵌 入式系统开发者应该对Little-endian和Big-endian模…

【RAC】How to Proceed from Failed 11gR2 CRS Installation

Applies to: [ID 942166.1] Oracle Server – Enterprise Edition – Version: 11.2.0.1 to 11.2.0.2 – Release: 11.2 to 11.2 Generic UNIX Generic Linux Goal This goal of this note is to provide steps to proceed from failed 11gR2 Grid Infrastructure installat…

WinForm支持拖拽效果

有一个MSDN客户提问在WinForm中如何实现拖拽效果——比如在WinForm中有一个Button&#xff0c;我要实现的效果是拖拽这个Button到目标位置后生成一个该控件的副本。 其实这个操作主要分成三步走&#xff1a; 1&#xff09;确定被拖拽的对象&#xff1a; 这里是Button&#xff0…

win7 64位出现桌面右键鼠标显示忙碌

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 将下面绿色内容复制到txt文本中&#xff0c;然后另存为1.bat 双击运行即可 【针对64位…

android tee,Android 9.0的新增安全特性与TEE

Android P&#xff0c;预计将于 2018 年第三季度发布最终版本。特别是Android8.0以来&#xff0c;安全性是Android版本变更的一个重要因素。从安全性增强方面来看&#xff0c;本次Android9.0版本主要有以下几个方面&#xff1a;统一的指纹身份验证对话框Android P 中&#xff0…

哪些要素会让咱们呈现抑郁症的病症

依据最新研讨标明&#xff0c;一自个的性情怎样&#xff0c;本来是天然生成的&#xff0c;后天的日子&#xff0c;仅仅对咱们的性情进行批改&#xff0c;但在咱们潜意识中&#xff0c;违反自个性情的行动&#xff0c;会让咱们感到格外累&#xff0c;所以&#xff0c;不少人即是…

如何定义一个只能在堆上(栈上)生成对象的类?

在C中&#xff0c;类的对象建立分为两种&#xff0c;一种是静态建立&#xff0c;如A a&#xff1b;另一种是动态建立&#xff0c;如A* ptrnew A&#xff1b;这两种方式是有区别的。 静态建立一个类对象&#xff0c;是由编译器为对象在栈空间中分配内存&#xff0c;是通过直接移…

canny算子的理论分析

****************************************************************************************************************************************** 红&#xff1a;数字图像处理视频教程&#xff08;两部&#xff09; {中科院版36讲视频教程 电子科大版70讲视频教程&#x…

Android为spinner设置适配器,Android Spinner与适配器模式详解及实例代码

最近做项目对Android Spinner 使用&#xff0c;这里简单写个小例子&#xff0c;来测试如何使用。Spinner是一个下拉列表&#xff0c;往安卓界面中拖拽一个Spinner控件&#xff0c;在属性中设置Android:entries“array/spinner_data”其中spinner_data为在string中设置的数组。数…

web框架-Struts开始

问题&#xff1a; 为什么有structs 作为一种框架&#xff08;frameset&#xff09;可以与传统的mvc进行比较&#xff1f; MVC是一种模式数据处理、显示和数据输入分开&#xff0c;来规范开发&#xff0c;但是却又并不规范。可以这样想&#xff1a;有三家公司&#xff0c;他们对…

加快上架方法

估计最近苹果app应用上架的比较多&#xff0c;审核比较慢&#xff0c;现在一个app从提交到上架短则7&#xff0c;8天&#xff0c;长则2&#xff0c;3个星期。我在实际上线应用时&#xff0c;总结了一个简单实用的小技巧&#xff0c;可以加快上架时间&#xff0c;最近使用这种方…

接口自动化测试 返回html,接口自动化测试实战(更新完毕)

前言自动化没练习的项目怎么办&#xff1f;自动化已经成为测试的必备技能之一了&#xff0c;所以&#xff0c;很多想跳槽的测试朋友都在自学&#xff0c;特别是最实用的接口自动化&#xff0c;但是很多人因为没有可以练手的项目而苦恼&#xff0c;最终导致缺乏实战经验&#xf…

Opencv 图像增强算法 图像检测结果及代码

****************************************************************************************************************************************** 红&#xff1a;数字图像处理视频教程&#xff08;两部&#xff09; {中科院版36讲视频教程 电子科大版70讲视频教程&#x…

php Hash Table(四) Hash Table添加和更新元素

HashTable添加和更新的函数&#xff1a; 有4个主要的函数用于插入和更新HashTable的数据: int zend_hash_add(HashTable *ht, char *arKey, uint nKeyLen,void **pData, uint nDataSize, void *pDest); int zend_hash_update(HashTable *ht, char *arKey, uint nKeyLen, void …

山寨“饿了么”应用中添加菜品数量按钮效果

山寨“饿了么”应用中添加菜品数量按钮效果 本人视频教程系类 iOS中CALayer的使用 最终效果&#xff1a; 山寨源头&#xff1a; 源码&#xff1a;&#xff08;此源码解决了重用问题&#xff0c;可以放心的放在cell中使用&#xff09; AddAndDeleteButton.h 与 AddAndDeleteBu…

html间数据传送,Express框架与html之间如何进行数据传递(示例代码)

关于Node.js 的Express框架介绍&#xff0c;推荐看菜鸟教程的Express框架&#xff0c;很适合入门&#xff0c;这里不再赘述&#xff0c;这里主要讲一下Express框架与html之间如何进行数据传递我采用的是JQuery的Ajax()向后台传参方式(url传参)1、Type属性为Get时&#xff1a;(1…

数字图像去噪典型算法及matlab实现

图像去噪是数字图像处理中的重要环节和步骤。去噪效果的好坏直接影响到后续的图像处理工作如图像分割、边缘检测等。图像信号在产生、传输过程中都可能会受到噪声的污染&#xff0c;一般数字图像系统中的常见噪声主要有&#xff1a;高斯噪声&#xff08;主要由阻性元器件内部产…

pat1100. Mars Numbers (20)

1100. Mars Numbers (20) 时间限制400 ms内存限制65536 kB代码长度限制16000 B判题程序Standard 作者CHEN, YuePeople on Mars count their numbers with base 13: Zero on Earth is called "tret" on Mars.The numbers 1 to 12 on Earch is called "jan, feb, …

【USACO1.1】Broken Necklace

题意 一个环形项链&#xff0c;有rbw三种珠子&#xff0c;r代表red&#xff0c;b代表blue&#xff0c;w代表white&#xff0c;从任意一个位置断开&#xff0c;两端分别取珠子&#xff0c;同一端取的珠子要相同颜色&#xff0c;w可以染成想要的颜色&#xff0c;即既可当作r也可以…

html+注释格式化,使用xml注释来生成格式化的html输出

我试图从我在xml文件中的注释中生成一个格式良好的html文档。目前我有一个xml文件&#xff0c;用于生成xml表格的html列表。为了让我添加有关表格的评论&#xff0c;我手动将注释添加到输出html文件中。使用xml注释来生成格式化的html输出我想如果可能将html代码放在xml文件中作…