iOS開發(fā)系列--Swift語言總結(jié).doc_第1頁
iOS開發(fā)系列--Swift語言總結(jié).doc_第2頁
iOS開發(fā)系列--Swift語言總結(jié).doc_第3頁
iOS開發(fā)系列--Swift語言總結(jié).doc_第4頁
iOS開發(fā)系列--Swift語言總結(jié).doc_第5頁
已閱讀5頁,還剩30頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、iOS 開發(fā)系列-Swift語言2015-08-10 12:09 by KenshinCui, 26622閱讀,57評論 ,收藏 ,編輯概述Swift 是蘋果2014 年推出的全新的編程語言,它繼承了C 語言、 ObjC 的特性,且克服了語言的兼容性問題。Swift 發(fā)展過程中不僅保留了ObjC 很多語法特性,它也借鑒了多種現(xiàn)代化語言的特點(diǎn),在其中你可以看到C#、 Java、Javascript、 Python 等多種語言的影子。同時(shí)C在 2015 年的 WWDC 上蘋果還宣布 Swift 的新版本 Swift2.0 ,并宣布稍后 Swift 即將開源,除了支持 iOS、 OS X之外還將支持

2、 linux 。本文將繼續(xù) iOS 開發(fā)系列教程, 假設(shè)讀者已經(jīng)有了其他語言基礎(chǔ) (強(qiáng)烈建議初學(xué)者從本系列第一章開始閱讀, 如果您希望從 Swift 學(xué)起,那么推薦你首先閱讀蘋果官方電子書 the swift programming language),不會(huì)從零基礎(chǔ)一點(diǎn)點(diǎn)剖析這門語言的語法,旨在幫助大家快速從 ObjC 快速過度到 Swift 開發(fā)中。即便如此,要盡可能全面的介紹 Swift 的語法特點(diǎn)也不是一件容易的事情,因此本文將采用較長的篇幅進(jìn)行介紹。創(chuàng)建一個(gè)命令行程序如下:import Foundation/* Swift 沒有 main 函數(shù),默認(rèn)從 top level code 的

3、上方開始自上而下執(zhí)行(因此不能有多個(gè)top level 代碼)*/println(Hello, World!)從上面的代碼可以看出:Swift 沒有 main 函數(shù),從 top level code 的上方開始往下執(zhí)行(就是第一個(gè)非聲明語句開始執(zhí)行 表達(dá)式或者控制結(jié)構(gòu),類、結(jié)構(gòu)體、枚舉和方法等屬于聲明語句),不能存在多個(gè)top levelcode 文件 (否則編譯器無法確定執(zhí)行入口,事實(shí)上數(shù)會(huì)設(shè)置并調(diào)用全局“C_ARGC C_ARGV”并調(diào)用由swift 隱含一個(gè)top level codemain 函數(shù),這個(gè)main構(gòu)成的 top_level_code()函函數(shù));Swift 通過 impo

4、rt 引入其他類庫(和Java比較像);Swift 語句不需要雙引號結(jié)尾(盡管加上也不報(bào)錯(cuò)),除非一行包含多條語句(和Python 有點(diǎn)類似);數(shù)據(jù)類型Swift 包含了 C 和 ObjC 語言中的所有基礎(chǔ)類型,Int 整形, Float 和 Double 浮點(diǎn)型, Bool 布爾型, Character 字符型, String 字符串類型;當(dāng)然還包括enum 枚舉、 struct 結(jié)構(gòu)體構(gòu)造類型;Array 數(shù)組、Set 集合、Dictionary 字典集合類型; 不僅如此還增加了高階數(shù)據(jù)類型元組(Tuple),可選類型( Optinal )。基礎(chǔ)類型Xcode 從 6.0 開始加入了Pla

5、yground 代碼測試,可以實(shí)時(shí)查看代碼執(zhí)行結(jié)果,下面使用Playground 簡單演示一下Swift 的基礎(chǔ)內(nèi)容,對Swift 有個(gè)簡單的認(rèn)識:import Foundationvar a:Int=1 /通過var定義一個(gè)變量/ 下面變量b 雖然沒有聲明類型,但是會(huì)自動(dòng)進(jìn)行類型推斷,這里b 推斷為Int類型var b=2var c:UInt=3let d=a+b / 通過let定義一個(gè)變量/ 下面通過 () 實(shí)現(xiàn)了字符串和變量相加println(d=(d) /結(jié)果: d=3(字符串插值),等價(jià)于println(d=+String(d)/ 注意由于 Swift 是強(qiáng)類型語言, a 是 Int

6、 類型而 c 是 UInt 類型,二者不能運(yùn)算,下面的語句報(bào)錯(cuò) ;但是注意如果是類似于:let a=1+2.0 是不會(huì)報(bào)錯(cuò)的,因?yàn)閮蓚€(gè)都是字面量,Swift 會(huì)首先計(jì)算出結(jié)果再推斷a 的類型/let e=a+c/Int.max是 Intlet e=Int.max /類型的最大值,類似還有Int.min 、 Int32.max 、 Int32.min結(jié)果: 9223372036854775807等var f:Float=1.0var g=2.0 / 浮點(diǎn)型自動(dòng)推斷為Double類型var h:String=hello /emoj 表情也可以作為變量或者常量,事實(shí)上所有 var ?=love an

7、d appleUnicode 字符都是可以的/ 兩個(gè)字符串相加,但是注意不同類型不能相加var i=h+? / 結(jié)果 :hello love and apple/ 布爾類型只有兩個(gè)值樣非 0即真true 、 false,類似于if語句中的條件只能是布爾類型不能像ObjC 一var j:Bool=true/ 字符類型, 同樣使用雙引號, 但是只能是一個(gè)字符, 如果不指定類型則 c 默認(rèn)會(huì)推斷為字符串( var k:Character=c 是字符類型,但是var k=c 是字符串類型)var k:Character=cvar l=00100 / 等于 100,可以在前面添加額外的0var m=10

8、_000_000 / 等于 10000000,可以使用增加額外的下劃線方便閱讀而不改變值的大小SwiftSwift通過 var 進(jìn)行變量定義, 通過 let 進(jìn)行常量定義(這和其他高級語言比較類似,添加了類型推斷,對于賦值的常量或者變量會(huì)自動(dòng)推斷其具體類型;例如F#);Swift 是強(qiáng)類型語言 (應(yīng)該說它比 C#、Java等強(qiáng)類型語言控制還要嚴(yán)格) ,不同的數(shù)據(jù)類型之間不能隱式轉(zhuǎn)化,如果需要轉(zhuǎn)化只能強(qiáng)制轉(zhuǎn)化;在 Swift 中類型轉(zhuǎn)換直接通過其類型構(gòu)造函數(shù)即可,降低了 API 的學(xué)習(xí)成本;集合類型Swift 提供了三種集合類型:數(shù)組Array、集合 Set、字典 Dictionary 。和 O

9、bjC 不同的是,由于 Swift 的強(qiáng)類型, 集合中的元素必須是同一類型,而不能像ObjC 一樣可以存儲(chǔ)任何對象類型,并且注意Swift 中的集合是值類型而非引用類型(事實(shí)上包括String、結(jié)構(gòu)體 struct 、枚舉enum 都是值類型) 。首先看一下Swift中的數(shù)組:/ 聲明數(shù)組的時(shí)候必須確定其類型,下面使用String 聲明一個(gè)字符串?dāng)?shù)組(String 是Array簡單表達(dá)形式)/var a:Array=hello,worldvar a:String=hello,worlda0 / 訪問數(shù)組元素/ 下面創(chuàng)建一個(gè) Double 類型的數(shù)組,這里沒有使用字面量,當(dāng)前是一個(gè)空數(shù)組,當(dāng)然也

10、可以寫成 var b:Double=var b=Double()for i in aprintln(i=(i)/ 添加元素, Swift 中可變類型不再由單獨(dú)的一個(gè)類型來表示,統(tǒng)統(tǒng)使用Array,如果想聲明為不可變數(shù)組只要使用let定義即可a.append(!)a+=I ,am ,Kenshin / 追加元素println(a.count=(a.count) /結(jié)果: a.count=6a3.5=I,Love,Swift /修改元素 ,但是注意無法用這種方式添加元素/a6=./ 這種方式是錯(cuò)誤的a.insert(New, atIndex: 5) /插入元素: hello world! I Lo

11、ve New Swifta.removeAtIndex(5) /刪除指定元素/ 使用全局 enumerate 函數(shù)遍歷數(shù)據(jù)索引和元素for (index,element) in enumerate(a)println(index=(index),element=(element)/ 使 用 構(gòu) 造 函 數(shù) 限 制 數(shù) 組 元 素 個(gè) 數(shù) 并 且 指 定 默 認(rèn) 值 , 等 價(jià) 于 var c=Array(count: 3, repeatedValue: 1) ,自動(dòng)推斷類型var c=Int(count: 3, repeatedValue: 1)Set 表示沒有順序的集合:/ 注意集合沒有類似

12、于數(shù)組的簡化形式,例如不能寫成var a:Set=hello,worldvar b:Set=1,2 / 類型推斷: Setvar a:String=hello,worlda.insert(!) /注意這個(gè)插入不保證順序if !a.isEmpty / 判斷是否為空a.remove(!)if !a.contains(!)a.insert(!)Dictionary 字典同樣是沒有順序的,并且在 Swift 中字典同樣要在使用時(shí)明確具體的類型。和ObjC 中一樣, 字典必須保證key 是唯一的, 而這一點(diǎn)就要求在Swift 中 key 必須是可哈希的,不過幸運(yùn)的是Swift 中的基本類型(如Int 、

13、Float、Double 、Bool、String)都是可哈希的,都可以作為key。/ 通 過 字 面 量 進(jìn) 行 字 典 初 始 化 , 注 意 等 價(jià) 于 var a:Dictionary=200:success,404:not foundvar a:Int:String=200:success,404:not foundvar b=200:success,404:not found /不聲明類型,根據(jù)值自動(dòng)推斷類型a200 / 讀取字典a404=can not found /修改a500=internal server error /添加/a=: / 設(shè)置為空字典,等價(jià)于: a=Int:

14、String()for code in a.keysprintln(code=(code)for description in a.valuesprintln(description=(description)for (code,description) in aprintln(code=(code),description=(description)注意:在 Swift 中集合的可變性不是像 ObjC 一樣由單獨(dú)的數(shù)據(jù)類型來控制的, 而是通過變量和常量來控制,這一點(diǎn)和其他高級語言比較類似。元組(Tuple)在開發(fā)過程中有時(shí)候會(huì)希望臨時(shí)組織一個(gè)數(shù)據(jù)類型, 此時(shí)可以使用一個(gè)結(jié)構(gòu)體或者類,由于這個(gè)

15、類型并沒有那么復(fù)雜,如果定義起來又比較麻煩,此時(shí)可以考慮使用元組。但是/* 元組的基本用法*/var point=(x:50,y:100) /自動(dòng)推斷其類型:(Int,Int)point.x /point.y /可以用類似于結(jié)構(gòu)體的方式直接訪問元素,結(jié)果:結(jié)果: 10050point.0 /point.1 /也可以采用類似數(shù)組的方式使用下標(biāo)訪問,結(jié)果:結(jié)果: 10050/ 元組也可以不指定元素名稱,訪問的時(shí)候只能使用下標(biāo)let frame:(Int,Int,Int,Float)=(0,0,100,100.0)println(frame) /結(jié)果: (0, 0, 100, 100.0)/ 注意下

16、面的語句是錯(cuò)誤的,如果指定了元組的類型則無法指定元素名稱/let frame:(Int,Int,Int,Int)=(x:0,y:0,width:100,height:100)var size=(width:100,25) / 僅僅給其中一個(gè)元素命名size.width / 結(jié)果: 100size.1 / 結(jié)果: 25var httpStatus:(Int,String)=(200,success) /元組的元素類型并不一定相同var(status,description)=httpStatus/ 一 次 性 賦 值 給 多 個(gè) 變 量 , 此 時(shí)description=successstatu

17、s=200,/ 接收元組的其中一個(gè)值忽略另一個(gè)值使用 _( 注意在 Swift 中很多情況下使用 _忽略某個(gè)值或變量 )var (sta,_)=httpStatusprintln(sta=(sta) /結(jié)果: sta=200/* 元組作為函數(shù)的參數(shù)或返回值,借助元組實(shí)現(xiàn)了函數(shù)的多個(gè)返回值*/func request()-(code:Int,description:String)return (404,not found)var result=request()result.0 / 結(jié)果: 404result.1 / 結(jié)果: not foundresult.code / 結(jié)果: 404resul

18、t.description / 結(jié)果: not found可選類型所謂可選類型就是一個(gè)變量或常量可能有值也可能沒有值則設(shè)置為可選類型。在ObjC 中如果一個(gè)對象類型沒有賦值,則默認(rèn)為nil,同時(shí) nil 類型也只能作為對象類型的默認(rèn)值,對于類似于 Int 等基本類型則對應(yīng) 0 這樣的默認(rèn)值。由于 Swift 是強(qiáng)類型語言,如果在聲明變量或常量時(shí)沒有進(jìn)行賦值, Swift 并不會(huì)默認(rèn)設(shè)置初值(這一點(diǎn)和其他高級語言不太一樣,例如 C#雖然也有可選類型,但是要求并沒有那么嚴(yán)格)。/* 可選類型基礎(chǔ)*/var x:Float? / 使用?聲明成一個(gè)可選類型,如果不賦值默認(rèn)為 nil x=172.0va

19、r y:Float=60.0/var z=x+y / 注意此句報(bào)錯(cuò), 因?yàn)?Int 和 Int?根本就是兩種不同的類型, 在 Swift 中兩種不同的類型不能運(yùn)算(因?yàn)椴粫?huì)自動(dòng)進(jìn)行類型轉(zhuǎn)化)var z=x!+y / 使用!進(jìn)行強(qiáng)制解包var age=29var ageInt=age.toInt() / 注意 ageInt 是 Int 可選類型而不是Int 類型(因?yàn)?String 的 toInt() 方法并不能保證其一定能轉(zhuǎn)化為Int 類型)Swift 中類似于Int 和 Int?并不是同一種類型,不能進(jìn)行相關(guān)運(yùn)算,如果要運(yùn)算只能解包;可選類型其本質(zhì)就是此類型內(nèi)部存儲(chǔ)分為“Some”和“ No

20、ne ”兩個(gè)部分,如果有值則存儲(chǔ)到“ Some”中,沒有值則為“None”(早期 Playground 中可以看到兩個(gè)部分,如今已經(jīng)取消顯示 Some 等描述了),使用感嘆號強(qiáng)制解包的過程就是取出“Some”部分;既然可選類型有可能有值,也可能沒有值那么往往有時(shí)候就需要判斷。可以使用if 直接判斷一個(gè)可選類型是否為 nil ,這樣一來就可以根據(jù)情況進(jìn)行強(qiáng)制解包 (從 Some 部分取出值的過程);另一個(gè)選擇就是在判斷的同時(shí)如果有值則將值賦值給一個(gè)臨時(shí)變量或常量,否則不進(jìn)入此條件語句,這個(gè)過程稱之為“可選綁定”。/* 可選類型判斷*/var age=29var ageInt=age.toInt(

21、) / 注意 ageInt 是 Int 可選類型而不是Int 類型(因?yàn)?String 的 toInt() 方法并不能保證其一定能轉(zhuǎn)化為Int 類型)if ageInt=nil println(ageInt=nil)elseprintln(ageInt=(ageInt!) /注意這里使用感嘆號!強(qiáng)制解析/* 可選類型綁定* 如果可選類型有值則將值賦值給一個(gè)臨時(shí)變量或者常量(此時(shí)此變量或者常量接受的值已經(jīng)不是可選類型) ,如果沒有值則不執(zhí)行此條件*/if let newAge=ageInt / 此時(shí) newAge 可以定義成常量也可以定義成變量 println(newAge=(newAge) /

22、 注意這里并不需要對 newAge 強(qiáng)制解包elseprintln(ageInt=nil)通過前面的演示可以看出Swift 中的可選綁定如果實(shí)際計(jì)算不得不進(jìn)行強(qiáng)制解包,如果一個(gè)可選類型從第一次賦值之后就能保證有值那么使用時(shí)就不必進(jìn)行強(qiáng)制解包了, 這種情況下可以使用隱式可選解析類型(通過感嘆號聲明而不是問號)/* 隱式解析可選類型*/var age:Int!=0 / 通過感嘆號聲明隱式解析可選類型,此后使用時(shí)雖然是可選類型但是不用強(qiáng)制解包age=29var newAge:Int=age /不用強(qiáng)制解包直接賦值給Int類型(程序會(huì)自動(dòng)解包)if var tempAge=age println(te

23、mpAge=(tempAge)elseprintln(age=nil)運(yùn)算符Swift 中支持絕大多數(shù)C 語言的運(yùn)算符并改進(jìn)以減少不必要的錯(cuò)誤(例如等號賦值后不返回值),算術(shù)運(yùn)算會(huì)檢查溢出情況,必要時(shí)還能使用新增的溢出運(yùn)算符。另外 Swift 中還可以對浮點(diǎn)數(shù)使用取余運(yùn)算符,新增了區(qū)間運(yùn)算符。對于基本的運(yùn)算符這里不再一一介紹,簡單看一下 Swift 中的區(qū)間運(yùn)算符和溢出運(yùn)算符。/* 區(qū)間運(yùn)算符,通常用于整形或者字符范圍(例如 a.z)*/for i in 1.5 / 閉區(qū)間運(yùn)算符.(從 1 到 5,包含 5)println(i=(i)for i in 1.5 / 半開區(qū)間運(yùn)算符.c100)/*

24、 元組匹配、值綁定、 where 條件匹配* 注意下面的匹配沒有 default ,因?yàn)樗怂星闆r*/var d=(x:900,y:0)switch dcase (0,0):println(d in (0,0)case (_,0): / 忽略 x 值匹配println(d in y)case (0,let y):/ 值綁定println(d in x,y=(y)case (-100.100,-100.100): / 注意這里有可能和第一、二、三個(gè)條件重合,但是Swift 允許多個(gè) case 匹配同一個(gè)條件,但是只會(huì)執(zhí)行第一個(gè)匹配println(x in ( 0-100 ),y in (0

25、-100 ) )case let (x,y) where x=y: /where條件匹配 ,注意這里的寫法等同于:(let x,let y) where x=yprintln(x=y=(x)case let (x, y):println(x=(x),y=(y)在其他語言中通??梢允褂胋reak、continue 、return ( Swift 中添加了fallthrough )等來終止或者跳出某個(gè)執(zhí)行語句,但是對于其行為往往是具有固定性的,例如 break 只能終止其所在的內(nèi)層循環(huán),而return 只能跳出它所在的函數(shù)。在Swift 中這種控制轉(zhuǎn)移功能得到了加強(qiáng),那就是使用標(biāo)簽。 利用標(biāo)簽?zāi)憧?/p>

26、以隨意指定轉(zhuǎn)移的位置,例如下面的代碼演示了如何直接通過標(biāo)簽跳出最外層循環(huán):var a=5whileLoop:while -a0 for var i=0;iIntreturn num1 + num2sum(1, 2)可以看到 Swift 中的函數(shù)僅僅表達(dá)形式有所區(qū)別 (定義形式類似于 Javascript,但是 js 不用書寫返回值 ),但是本質(zhì)并沒有太大的區(qū)別。 不過 Swift 中對函數(shù)參數(shù)強(qiáng)調(diào)兩個(gè)概念就是局部參數(shù)名(又叫“形式參數(shù)” )和外部參數(shù)名,這極大的照顧到了 ObjC 開發(fā)者的開發(fā)體驗(yàn)。在上面的例子中調(diào)用 sum 函數(shù)并沒有傳遞任何參數(shù)名,因?yàn)?num1、 num2 僅僅作為局部參

27、數(shù)名在函數(shù)內(nèi)部使用, 但是如果給函數(shù)指定一個(gè)外部參數(shù)名在調(diào)用時(shí)就必須指定參數(shù)名。 另外前面也提到關(guān)于 Swift 中的默認(rèn)參數(shù)、 可變長度的參數(shù), 包括一些高級語言中的輸入輸出參數(shù),通過下面的例子大家會(huì)有一個(gè)全面的了解。/*/* 函數(shù)參數(shù)名分為局部參數(shù)名和外部參數(shù)名*/func split(string a:String,seperator b:Character)-Stringreturn split(a, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=b)/ 由于給 split 函數(shù)設(shè)置了外部參數(shù)名 string 和

28、 seperator ,所以執(zhí)行的時(shí)候必須帶上外部參數(shù)名,此處可以看到一個(gè)有意義的外部參數(shù)名大大節(jié)省開發(fā)者使用成本split(string: hello,world,!, seperator: ,) /結(jié)果: hello, world, !/ 下面通過在局部參數(shù)名前加上 #來簡寫外部參數(shù)名(此時(shí)局部參數(shù)名和外部參數(shù)名相同)func split2(#string:String,#seperator:Character)-Stringreturn split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=se

29、perator)split2(string: hello,world,!, seperator: ,)/ 上面的 split 函數(shù)的最后一個(gè)參數(shù)默認(rèn)設(shè)置為 , 注意如果使用默認(rèn)參數(shù)那么此參數(shù)名將默認(rèn)作為外部參數(shù)名(此時(shí)局部參數(shù)名和外部參數(shù)名相同)func split3(#string:String,seperator:Character=,)-Stringreturn split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=seperator)split3(string: hello,world,!,

30、seperator: ,) /結(jié)果: hello, world, !split3(string: hello world !, seperator: ) /結(jié)果: hello, world, !/ 但是如果有默認(rèn)值,又不想指定局部參數(shù)名可以使用“_”取消外部參數(shù)名func split4(string:String,_ seperator:Character=,)-Stringreturn split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=seperator)split4(hello,world,!

31、, ,) /結(jié)果: hello, world, !/* 可變參數(shù) ,一個(gè)函數(shù)最多有一個(gè)可變參數(shù)并且作為最后一個(gè)參數(shù)* 下面 strings 參數(shù)在內(nèi)部是一個(gè)String ,對于外部是不定個(gè)數(shù)的String 參數(shù)*/func joinStr(seperator:Character=,strings:String.)-Stringvar result:String=for var i=0;iIntnum1 = num1 + num2return num1sum2(1, 2) / 結(jié)果: 3/* 輸入輸出參數(shù)* 通過輸入輸出參數(shù)可以在函數(shù)內(nèi)部修改函數(shù)外部的變量(注意調(diào)用時(shí)不能是常量或字面量)*注意:

32、下面的swap 僅僅為了演示,實(shí)際使用時(shí)請用Swift 的全局函數(shù)swap*/func swap(inout a:Int ,inout b:Int)a=a+bb=a-ba=a-bvar a=1,b=2swap(&a, &b) / 調(diào)用時(shí)參數(shù)加上“& ”符號println(a=(a),b=(b) /結(jié)果: a=2,b=1和很多語言一樣,Swift 中的函數(shù)本身也可以看做一種類型,既可以作為參數(shù)又可以作為返回值。/* 函數(shù)類型*/var sum3=sum / 自動(dòng)推斷sum3 的類型: (Int,Int)-Int, 注意不同的函數(shù)類型之間不能直接賦值sum3(1,2) / 結(jié)果: 3/ 函數(shù)作為返

33、回值func fn()-(Int,Int)-Int/ 下面的函數(shù)是一個(gè)嵌套函數(shù),作用于是在fn 函數(shù)內(nèi)部func minus(a:Int,b:Int)-Intreturn a-breturn minus;var minus=fn()/ 函數(shù)作為參數(shù)func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Intreturn fn(num1,num2)caculate(1, 2, sum) / 結(jié)果: 3caculate(1,2, minus) / 結(jié)果: -1閉包Swift 中的閉包其實(shí)就是一個(gè)函數(shù)代碼塊,它和ObjC 中的 Block 及 C#、 J

34、ava 中的 lambda 是類似的。 閉包的特點(diǎn)就是可以捕獲和存儲(chǔ)上下文中的常量或者變量的引用, 即使這些常量或者變量在原作用域已經(jīng)被銷毀了在代碼塊中仍然可以使用。 事實(shí)上前面的全局函數(shù)和嵌套函數(shù)也是一種閉包, 對于全局函數(shù)它不會(huì)捕獲任何常量或者變量, 而對于嵌套函數(shù)則可以捕獲其所在函數(shù)的常量或者變量。 通常我們說的閉包更多的指的是閉包表達(dá)式, 也就是沒有函數(shù)名稱的代碼塊,因此也稱為匿名閉包。在Swift中閉包表達(dá)式的定義形式如下: ( parameters ) - returnType instatements下面通過一個(gè)例子看一下如何通過閉包表達(dá)式來簡化一個(gè)函數(shù)類型的參數(shù),閉包的形式也是

35、一而再再而三的被簡化,充分說明了Swift 語法的簡潔性:在下面的例子中func sum(num1:Int,num2:Int)-Intreturn num1 + num2func minus(num1:Int,num2:Int)-Intreturn num1 - num2func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Intreturn fn(num1,num2)var (a,b)=(1,2)caculate(a, b, sum) / 結(jié)果: 3caculate(a, b, minus) / 結(jié)果:-1/ 利用閉包表達(dá)式簡化閉包函數(shù)cacul

36、ate(a, b, (num1:Int,num2:Int)-Int inreturn num1 - num2) /結(jié)果:-1/ 簡化形式,根據(jù)上下文推斷類型并且對于單表達(dá)式閉包(只有一個(gè)語句)可以隱藏return關(guān)鍵字caculate(a, b, num1,num2 innum1 - num2) / 結(jié)果: -1/ 再次簡化,使用參數(shù)名縮寫 ,使用 $0.$n 代表第 n 個(gè)參數(shù),并且此 in 關(guān)鍵字也省略了 caculate(a, b, $0-$1) / 結(jié)果: -1考慮到閉包表達(dá)式的可讀取性, Swift 中如果一個(gè)函數(shù)的最后一個(gè)參數(shù)是一個(gè)函數(shù)類型的參數(shù)(或者說是閉包表達(dá)式) ,則可以將此

37、參數(shù)寫在函數(shù)括號之后,這種閉包稱之為“尾隨閉包”。func sum(num1:Int,num2:Int)-Intreturn num1 + num2func minus(num1:Int,num2:Int)-Intreturn num1-num2func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Intreturn fn(num1,num2)var (a,b)=(1,2)/ 尾隨閉包,最后一個(gè)參數(shù)是閉包表達(dá)式時(shí)可以卸載括號之后,同時(shí)注意如果這個(gè)函數(shù)只有一個(gè)閉包表達(dá)式參數(shù)時(shí)可以連通括號一塊省略/ 請注意和函數(shù)定義進(jìn)行區(qū)分caculate(a, b)

38、$0-$1 / 結(jié)果: -1前面說過閉包之所以稱之為 “閉包” 就是因?yàn)槠淇梢圆东@一定作用域內(nèi)的常量或者變量進(jìn)而閉合并包裹著。func add()-()-Intvar total=0var step=1func fn()-Inttotal+=stepreturn totalreturn fn/fn 捕獲了 total 和 step ,盡管下面的add() 執(zhí)行完后total了二者的副本,所以fn 會(huì)隨著兩個(gè)變量的副本一起被存儲(chǔ)和step被釋放,但是由于fn捕獲var a=add()a() / 結(jié)果:1a() / 結(jié)果:2,說明a 中保存了total的副本(否則結(jié)果會(huì)是1)var b=add()

39、b() / 結(jié)果: 1 ,說明 a 和 b 單獨(dú)保存了total 的副本(否則結(jié)果會(huì)是3)var c=bc() / 結(jié)果: 2,說明閉包是引用類型,換句話說函數(shù)是引用類型(否則結(jié)果會(huì)是1)Swift 會(huì)自動(dòng)決定捕獲變量或者常量副本的拷貝類型(值拷貝或者引用拷貝)而不需要開發(fā)者關(guān)心,另外被捕獲的變量或者常量的內(nèi)存管理同樣是由Swift 來管理,例如當(dāng)上面的函數(shù)a 不再使用了那么fn 捕獲的兩個(gè)變量也就釋放了。類作為一門面向?qū)ο笳Z言,類當(dāng)然是Swift 中的一等類型。 首先通過下面的例子讓大家對Swift的 class 有一個(gè)簡單的印象,在下面的例子中可以看到Swift 中的屬性、 方法(包括構(gòu)造

40、方法和析構(gòu)方法):/Swift 中一個(gè)類可以不繼承于任何其他基類,那么此類本身就是一個(gè)基類 class Person / 定義屬性var name:Stringvar height=0.0/ 構(gòu)造器方法,注意如果不編寫構(gòu)造方法默認(rèn)會(huì)自動(dòng)創(chuàng)建一個(gè)無參構(gòu)造方法init(name:String)=name/ 定義方法func showMessage()println(name=(name),height=(height)/ 析構(gòu)方法,在對象被釋放時(shí)調(diào)用 ,類似于 ObjC 的 dealloc ,注意此函數(shù)沒有括號,沒有參數(shù),無法直接調(diào)用deinitprintln(deinit.)var p=Person(name: Kenhin)p.height=172.0p.showMessage() / 結(jié)果: name=Kenhin,height=172.0/ 類是引用類型var p2 = = Kaoruprintln() /結(jié)果: Kaoruif p = p2 / “ =”表示等價(jià)于,這里不能使用等于“ =”(等于用于比較值相等, p 和 p2 是不同的值,只是指向的對象相同)println(p=p2) /p等價(jià)于 p2,二者指向同一個(gè)對象從上面的例子不難看出:Swift中的類不必須繼承一個(gè)基類(但是Ob

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論