介紹:編程
Swift是蘋果2014年推出的全新編程語言,它繼承了C語言、ObjC的特性,且克服了C語言的兼容性問題。Swift發展過程不只保留了Objc不少語言特性,他也借鑑了多種現代化語言的特色,在其中能夠看到C#、Java、JavaScript、Python等多種語言的影子。同時在2015年WWDC上蘋果還宣佈了Swift的新版本Swift2.0,Swift是開源的,還支持iOS、OS X、Linux。swift
Swift2.0官方中文版+100個必備tips:http://download.csdn.net/detail/shaoting19910730/9189677數組
基礎部分:app
第一個Swift程序:編程語言
1 import Foundation 2 3 /** 4 * Swift沒有main函數,默認從top level code的上方開始自上而下執行(所以不能有多個top level代碼) 5 */ 6 println("Hello, World!")
從上面得代碼能夠看出:ide
一、Swift沒有main函數,從top level code的上方開始往下執行 ,即第一個非聲明語句開始執行(表達式、控制結構、類、結構體、枚舉、方法等屬於聲明語句),不能存在多個top level code文件,不然編譯器不能肯定執行入口,事實上swift隱含了一個main函數,這個main函數會設置而且調用全局「C_ARGC C_ARGV」並調用由top level code構成的top_level_code()函數。函數
二、Swift經過import引入其餘類庫。oop
三、Swift語句不須要雙引號結尾,除非一行之中有多個語句。學習
數據類型 測試
Swift包含了C和Objc語句中的全部基礎類型:Int整形、Float和Double浮點型、Bool布爾型、Character字符型、String字符串類型、enum枚舉、struct結構體構造類型、Array數組、Set集合、Dictionary字典集合類型,不只如此還增長了高階數據類型:元組(Tuple),可選類型(Optinal)。
基礎類型
Xcode從6.0開始加入了Playground代碼測試,能夠實時查看代碼執行結果,下面使用Playground簡單演示一下Swift的基礎內容,對Swift有個簡單的認識:
1 import Foundation 2 3 var a:Int=1 //經過var定義一個變量 4 5 //下面變量b雖然沒有聲明類型,可是會自動進行類型推斷,這裏b推斷爲Int類型 6 var b=2 7 8 var c:UInt=3 9 let d=a+b //經過let定義一個常量 10 11 //下面經過"\()"實現了字符串和變量相加(字符串插值),等價於println("d="+String(d)) 12 println("d=\(d)") //結果:d=3 13 14 //注意因爲Swift是強類型語言,a是Int類型而c是UInt類型,兩者不能運算,下面的語句報錯;可是注意若是是相似於:let a=1+2.0是不會報錯的,由於兩個都是字面量,Swift會首先計算出結果再推斷a的類型 15 //let e=a+c 16 17 //Int.max是Int類型的最大值,相似還有Int.min、Int32.max、Int32.min等 18 let e=Int.max //結果:9223372036854775807 19 20 var f:Float=1.0 21 var g=2.0 //浮點型自動推斷爲Double類型 22 23 var h:String="hello " 24 25 //emoj表情也能夠做爲變量或者常量,事實上全部Unicode字符都是能夠的 26 var 💖🍎="love and apple" 27 28 //兩個字符串相加,可是注意不一樣類型不能相加 29 var i=h+💖🍎 //結果:hello love and apple 30 31 //布爾類型只有兩個值true、false,相似於if語句中的條件只能是布爾類型不能像ObjC同樣非0即真 32 var j:Bool=true 33 34 //字符類型,一樣使用雙引號,可是隻能是一個字符,若是不指定類型則"c"默認會推斷爲字符串(var k:Character="c"是字符類型,可是var k="c"是字符串類型) 35 var k:Character="c" 36 37 var l=00100 //等於100,能夠在前面添加額外的0 38 var m=10_000_000 //等於10000000,可使用增長額外的下劃線方便閱讀而不改變值的大小
一、Swift經過var進行變量定義,經過let進行常量定義。
二、Swift添加了類型推斷,對於賦值的常量或者變量會自動推斷其具體類型。
三、Swift是強類型語言,不一樣的數據類型之間不能隱式轉換,若是須要轉換隻能強制轉換。
四、在Swift中類型轉換直接經過其類型構造函數便可,下降了API的學習成本。
集合類型:
Swift提供了三種集合類型:數組Array、集合Set、字典Dictionary。和Objc不一樣的是,因爲Swift的強類型,集合中的元素必須是同一類型,而不能像Objc同樣能夠儲存任何對象類型,而且注意Swift中的集合是值類型二非引用類型(string、結構體struct、枚舉enum都是值類型)。
首先看一下Swift中的數組:
1 //聲明數組的時候必須肯定其類型,下面使用[String]聲明一個字符串數組([String]是Array<String>簡單表達形式) 2 //var a:Array<String>=["hello","world"] 3 var a:[String]=["hello","world"] 4 a[0] //訪問數組元素 5 6 //下面建立一個Double類型的數組,這裏沒有使用字面量,當前是一個空數組,固然也能夠寫成var b:[Double]=[] 7 var b=[Double]() 8 9 for i in a{ 10 println("i=\(i)") 11 } 12 13 //添加元素,Swift中可變類型再也不由單獨的一個類型來表示,通通使用Array,若是想聲明爲不可變數組只要使用let定義便可 14 a.append("!") 15 16 a+=["I" ,"am" ,"shaoting"] //追加元素 17 18 println("a.count=\(a.count)") //結果:a.count=6 19 20 a[3...5]=["I","Love","Swift"] //修改元素,可是注意沒法用這種方式添加元素 21 //a[6]=["."]//這種方式是錯誤的 22 23 a.insert("New", atIndex: 5) //插入元素:hello world! I Love New Swift 24 25 a.removeAtIndex(5) //刪除指定元素 26 27 //使用全局enumerate函數遍歷數據索引和元素 28 for (index,element) in enumerate(a){ 29 println("index=\(index),element=\(element)") 30 } 31 32 //使用構造函數限制數組元素個數而且指定默認值,等價於var c=Array(count: 3, repeatedValue: 1),自動推斷類型 33 var c=[Int](count: 3, repeatedValue: 1)
Set表示沒有順序的集合:
1 //注意集合沒有相似於數組的簡化形式,例如不能寫成var a:[String]=["hello","world"] 2 var a:Set<String>=["hello","world"] 3 var b:Set=[1,2] //類型推斷:Set<Int> 4 5 a.insert("!") //注意這個插入不保證順序 6 7 if !a.isEmpty { //判斷是否爲空 8 a.remove("!") 9 } 10 11 if !a.contains("!"){ 12 a.insert("!") 13 }
DIctionary字典一樣是沒有順序的,而且在Swift中字典一樣要在使用時明確具體的類型。和Objc中同樣,字典必須保證key是惟一的,而這一點就要求在Swift中的key必須是可哈希的,不過幸運的是Swift中的基本類型(如Int、Float、Double、Bool、String)都是可哈希的,均可以做爲key。
1 //經過字面量進行字典初始化,注意等價於var a:Dictionary<Int,String>=[200:"success",404:"not found"] 2 var a:[Int:String]=[200:"success",404:"not found"] 3 var b=[200:"success",404:"not found"] //不聲明類型,根據值自動推斷類型 4 5 a[200] //讀取字典 6 a[404]="can not found" //修改 7 8 a[500]="internal server error" //添加 9 //a=[:] //設置爲空字典,等價於:a=[Int:String]() 10 11 for code in a.keys{ 12 println("code=\(code)") 13 } 14 15 for description in a.values{ 16 println("description=\(description)") 17 } 18 19 for (code,description) in a{ 20 println("code=\(code),description=\(description)") 21 }
注意:在Swift中集合的可變性不是像Objc同樣由單獨的數據類型來控制的,而是經過變量和常量來控制,這一點和其餘高級語言比較相似。
元組(Tuple)
在開發過程當中, 有時會能夠臨時組織一個數據類型,此時可使用一個結構體或者類,可是因爲這個類型並無那麼複雜,若是定義起來有比較複雜,此時能夠考慮使用元組。
1 /** 2 * 元組的基本用法 3 */ 4 var point=(x:50,y:100) //自動推斷其類型:(Int,Int) 5 point.x //能夠用相似於結構體的方式直接訪問元素,結果:50 6 point.y //結果:100 7 point.0 //也能夠採用相似數組的方式使用下標訪問,結果:50 8 point.1 //結果:100 9 10 //元組也能夠不指定元素名稱,訪問的時候只能使用下標 11 let frame:(Int,Int,Int,Float)=(0,0,100,100.0) 12 println(frame) //結果:(0, 0, 100, 100.0) 13 14 //注意下面的語句是錯誤的,若是指定了元組的類型則沒法指定元素名稱 15 //let frame:(Int,Int,Int,Int)=(x:0,y:0,width:100,height:100) 16 17 18 var size=(width:100,25) //僅僅給其中一個元素命名 19 size.width //結果:100 20 size.1 //結果:25 21 22 23 var httpStatus:(Int,String)=(200,"success") //元組的元素類型並不必定相同 24 25 var (status,description)=httpStatus //一次性賦值給多個變量,此時status=200,description="success" 26 27 //接收元組的其中一個值忽略另外一個值使用"_"(注意在Swift中不少狀況下使用_忽略某個值或變量) 28 var (sta,_)=httpStatus 29 println("sta=\(sta)") //結果:sta=200 30 31 /** 32 * 元組做爲函數的參數或返回值,藉助元組實現了函數的多個返回值 33 */ 34 func request()->(code:Int,description:String){ 35 return (404,"not found") 36 } 37 var result=request() 38 result.0 //結果:404 39 result.1 //結果:not found 40 result.code //結果:404 41 result.description //結果:not found
可選類型
所謂可選類型就是一個變量或者常量可能有值也可能沒有值,則可設置爲可選類型。在Objc中若是一個對象類型沒有賦值,則默認爲nil,同時nil類型也只能做爲對象類型的默認值,對於相似於Int等基本類型則對應0這樣的默認值。因爲Swift是強類型語言,若是在聲明變量或常量時沒有進行賦值,Swift並不會默認初值。
/** * 可選類型基礎 */ var x:Float? //使用?聲明成一個可選類型,若是不賦值默認爲nil x=172.0 var y:Float=60.0 //var z=x+y //注意此句報錯,由於Int和Int?根本就是兩種不一樣的類型,在Swift中兩種不一樣的類型不能運算(由於不會自動進行類型轉化) var z=x!+y //使用!進行強制解包 var age="29" var ageInt=age.toInt() //注意ageInt是Int可選類型而不是Int類型(由於String的toInt()方法並不能保證其必定能轉化爲Int類型)
一、Swift中相似Int和Int?並非同一種類型,不能進行相關運算,若是要運算只能解包。
二、可選類型其本質就是此類型內部存儲分爲「Some」和「None」兩個部分,若是有值則存儲到「Some」中,沒有值則存儲到「None」,使用感嘆號強制解包的過程就是取出「Some」部分,既然可選類型可能有值,也可能沒有值,這個時候就須要判斷,可使用if直接判斷一個可選類型是否爲nil,這樣一來就能夠根據狀況進行強制解包,另一個選擇:判斷的時候若是有值則將值賦值給另一個臨時變量或常量,這個過程稱爲「可選綁定」。
1 /** 2 * 可選類型判斷 3 */ 4 var age="29" 5 var ageInt=age.toInt() //注意ageInt是Int可選類型而不是Int類型(由於String的toInt()方法並不能保證其必定能轉化爲Int類型) 6 7 if ageInt==nil { 8 println("ageInt=nil") 9 }else{ 10 println("ageInt=\(ageInt!)") //注意這裏使用感嘆號!強制解析 11 } 12 13 /** 14 * 可選類型綁定 15 * 若是可選類型有值則將值賦值給一個臨時變量或者常量(此時此變量或者常量接受的值已經不是可選類型),若是沒有值則不執行此條件 16 */ 17 if let newAge=ageInt{ //此時newAge能夠定義成常量也能夠定義成變量 18 println("newAge=\(newAge)") //注意這裏並不須要對newAge強制解包 19 }else{ 20 println("ageInt=nil") 21 }
經過前面的演示能夠看出Swift中的可選綁定若是實際計算不得不進行強制解包,若是一個可選類型從第一次賦值以後就能保證有值那麼使用時就沒必要進行強制解包了,這樣狀況下可使用隱式可選解析類型,經過感嘆號聲明。
/** * 隱式解析可選類型 */ var age:Int!=0 //經過感嘆號聲明隱式解析可選類型,此後使用時雖然是可選類型可是不用強制解包 age=29 var newAge:Int=age //不用強制解包直接賦值給Int類型(程序會自動解包) if var tempAge=age { println("tempAge=\(tempAge)") }else{ println("age=nil") }
運算符:
Swift中支持絕大多數C語言的運算符並改進以減小沒必要要的錯誤(例如等號賦值後不返回值),算術運算會檢查溢出狀況,必要時還能使用新增的溢出運算符。另外Swift中還能夠對浮點數使用取餘運算符,新增了區間運算符。對於基本的運算符這裏再也不一一介紹,簡單看一下Swift中的區間運算符和溢出運算符。
1 /** 2 * 區間運算符,一般用於整形或者字符範圍(例如"a"..."z") 3 */ 4 for i in 1...5 { //閉區間運算符...(從1到5,包含5) 5 println("i=\(i)") 6 } 7 8 for i in 1..<5{ //半開區間運算符..<(從1到4) 9 println("i=\(i)") 10 } 11 12 var str = "hello world." 13 var range="a"..."z" 14 for t in str { 15 if range.contains(String(t)) { 16 print(t) //結果:helloworld 17 } 18 } 19 20 /** 21 * 溢出運算符 22 */ 23 var a=UInt8.max //a=255 24 //var b:UInt8=a+1 //注意b會出現溢出,此句報錯 25 26 //下面使用溢出運算符,結果爲:0,相似的還有&-、&*、&/ 27 //使用溢出運算符能夠在最大值和最小值以前循環而不會報錯 28 var b:UInt8=a &+ 1
溢出運算符的原理其實很簡單,例如對於UInt8,若是8位均爲1則十進制表示是255,可是當加1以後則變成了9位「100000000」,出現了溢出可是UInt8自己值只能存儲8位,因此取後面8位就變成了「00000000」,十進制表示就是0.
控制流
Swift中的多數控制流和其餘語句差異並不大,例如for、while、do while、if、switch等,這裏介紹一些不一樣點。
1 var a=["a","b","c","d","e","f","g"] 2 let b=a[1] 3 /** 4 * switch支持一個case多個模式匹配,同時case後不用寫break也會在匹配到種狀況後自動跳出匹配,不存在隱式貫穿,若是想要貫穿在case以後添加"fallthrough"關鍵字 5 */ 6 switch b{ 7 case "a","b": 8 println("b=a or b=b") 9 case "c","d","e","f": 10 println("b in (c,d,e,f)") 11 default: 12 println("b=g") 13 } 14 15 /** 16 * 匹配區間,同時注意switch必須匹配全部狀況,不然必須加上default 17 */ 18 19 let c:Int=88 20 switch c{ 21 case 1...60: 22 println("1-60") 23 case 61...90: 24 println("61-90") 25 case 91...100: 26 println("91-100") 27 default: 28 println("1>c>100") 29 } 30 31 /** 32 * 元組匹配、值綁定、where條件匹配 33 * 注意下面的匹配沒有default,由於它包含了全部狀況 34 */ 35 var d=(x:900,y:0) 36 switch d{ 37 case (0,0): 38 println("d in (0,0)") 39 case (_,0): //忽略x值匹配 40 println("d in y") 41 case (0,let y)://值綁定 42 println("d in x,y=\(y)") 43 case (-100...100,-100...100): //注意這裏有可能和第1、2、三個條件重合,可是Swift容許多個case匹配同一個條件,可是隻會執行第一個匹配 44 println("x in(0-100),y in (0-100)") 45 case let (x,y) where x==y: //where條件匹配,注意這裏的寫法等同於:(let x,let y) where x==y 46 println("x=y=\(x)") 47 case let (x, y): 48 println("x=\(x),y=\(y)") 49 50 }
在其餘語言中一般可使用break、continue、return(Switch中添加了fallthrough)等來終止或者跳出某個執行語句,可是它們的功能通常都是固定的,例如break只能終止其所在的內層循環,而return只能跳出它所在的函數。在Swift中這種控制轉移功能獲得了增強,可使用標籤跳轉至任意指定的位置,下面就是使用標籤直接跳出最外層循環:
1 var a=5 2 whileLoop: 3 while --a>0 { 4 for var i=0;i<a;++i{ 5 println("a=\(a),i=\(i)") 6 7 break whileLoop 8 //若是此處直接使用break將跳出for循環,而因爲這裏使用標籤直接跳出了while,結果只會打印一次,其結果爲:a=4,i=0 9 } 10 }