窺探Swift之數組安全索引與數組切片

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文件中作…