Swift資料型別
1.基礎資料型別:整形Int、浮點數Double和Float、布林型別Bool,字串型別String。 2.集合資料型別,Array和Dictionary 3.元組型別 4.結構體struct,列舉enum,類:class 5.數值型別 和 引用型別 (1)數值型別是說當它被賦值給一個常量或者變數,或者作為引數傳遞給函式時,是完整地複製了一個新的數值,而不是僅僅改變了引用物件。 (2)所有Swift中的基礎型別-整型,浮點型,布林型別,字串,陣列和字典都是數值型別。它們也都是由結構來實現的。 (3)在Swift中所有的結構和列舉型別都是數值型別。這意味這你例項化的每個結構和列舉,其包含的所有屬性,都會在程式碼中傳遞的時候被完整複製。 (4)類 和 函式 閉包 是引用型別 (5)當一個值型別例項作為常量而存在,它的所有屬性也作為常量而存在。類是引用型別。如果你將引用型別的例項賦值給常量,依然能夠改變例項的變數屬性。
?和 ! 參見博文:joeyio.com/ios/2014/06…
字典和陣列 1.都用[] 2.空陣列 和 空字典 var emptyArray = String (或者 Array() ) let emptyDictionary = Dictionary<String,Int>() 或者 var emptyArr:String[] = [] 或者 var emptyArray = Array([]) //用陣列建立陣列 對於已知型別的字典可用[:]置空 var arr = [] //直接這樣寫arr是個空的NSArray 3.確定長度和預設值的陣列 var threeDoubles = Double[](count: 3, repeatedValue: 0.0) 4.用只讀屬性count來讀取陣列和字典的長度 5.用屬性isEmpty檢查陣列的長度是否為0 6.往陣列追加元素 emptyArray.append("one") emptyArray += "two" emptyArray += [ "three" , "four" ] emptyArray.insert("zero" , atIndex:0) 7.從陣列中刪除元素 let lastElement = emptyArray.removeLast() //刪除最後一個 let indexElement = emptyArray.removeAtIndex(3) //按索引刪除 emptyArray[0...2] = [] //區間元素替換
- 遍歷陣列 for (index, value) in enumerate(emptyArray) { println("Item (index): (value)") }
- 給字典增加元素 emptyDictionary["zero"] = 0 if let oldValue = emptyDictionary.updateValue(1, forKey: "one") { println("The old value for key:one was (oldValue).") } //增加或更新元素 10.移除字典元素 emptyDictionary["zero"] = nil let oldValue = emptyDictionary.removeValueForKey("one") emptyDictionary.removeAll() 11.遍歷字典 for (key, value) in dic { println("(key): (value)") } 12.獲取字典的keys和values let keys = Array(dic.keys) let values = Array(dic.values) 13.陣列的copy方法 通過呼叫陣列的copy方法來完成強制拷貝。這個方法將會完整複製一個陣列到新的陣列中。 14.陣列的unshare方法 如果多個變數引用了同一個陣列,可以使用unshare方法來完成一次“獨立”區間 ..生成 [ ) 的區間,而…生成 [ ] 的區間 元組(Tuple) 元組型別可以將一些不同的資料型別組裝成一個元素 var yuZu = ( 404 , "error" ) println( yuZu ) var ( one:Int , two:String ) = yuZu println( one ) println( two )
2.使用 _ 來忽略不需要的值 var ( one:Int , _ ) = yuZu
println( one ) 3.使用元素序號來選擇元組中的值,從0開始 var tuple = ( 404 , "error" ) println( tuple.0 ) 4.使用 元組名.元素名 訪問
var tuple = ( eN:404 , eT:"error" ) println( tuple.eN )
函式
1.帶有變長引數的函式 func matableFunc( names: String... ) { for name in names { println(name) } } matableFunc() matableFunc("x","j","x") 2.輸入-輸出引數 inout 一個輸入-輸出引數都有一個傳遞給函式的值,由函式修改後,從函式返回來替換原來的值 func printAndCount(inout stringToPrint: String) -> Int {}
列舉enum 1.列舉可以關聯方法 2.使用toRaw和fromRaw在原始數值和列舉值之間進行轉換
結構體Struct 1.支援構造器和方法 2.結構和類的最大區別在於:結構的例項按值傳遞(passed by value),而類的例項按引用傳遞(passed by reference) 3.結構型別有一種成員逐一完成初始化的構造器,類不存在成員逐一構造器
類 class 1.重寫一個由繼承而來的方法需要在方法定義前標註override關鍵詞。 2.@final 用來標記一個類不被繼承或者一個方法不被重寫 3.型別方法 在類結構體裡面用class func開頭 ,對於列舉和結構來說,型別方法是用static func開頭。 4. 便捷初始化. convenience init() { self.init(name: "[Unnamed]") } 5.weak:弱引用必須宣告為變數 及 可選型別 6.unowned:無主引用不能為可選型別
兩階段初始化 在Swift中,類的初始化要經過兩個階段 (1)第一個階段,每一個儲存屬性都被設定了一個初始值。 (2)在第二個階段,每個類在這個例項被使用之前都會有機會來設定它們相應的儲存屬性
協議protocol 1.Swift使用protocol定義協議 2.Protocol(協議)用於統一方法和屬性的名稱,而不實現任何功能。協議能夠被類,列舉,結構體實現,滿足協議要求的類,列舉,結構體被稱為協議的遵循者 3.屬性要求 通常前置var關鍵字將屬性宣告為變數。在屬性宣告後寫上{ get set }表示屬性為可讀寫的。{ get }用來表示屬性為可讀的。即使你為可讀的屬性實現了setter方法,它也不會出錯。 protocol SomeProtocol { var musBeSettable : Int { get set } var doesNotNeedToBeSettable: Int { get } } 4.方法要求 協議能夠要求其遵循者必備某些特定的例項方法和類方法。協議方法的宣告與普通方法宣告相似,但它不需要方法內容. 協議方法支援變長引數(variadic parameter),不支援預設引數(default parameter)。 5.突變方法要求 能在方法或函式內部改變例項型別的方法稱為突變方法。在值型別(Value Type)(譯者注:特指結構體和列舉)中的的函式字首加上mutating關鍵字來表示該函式允許改變該例項和其屬性的型別 類中的成員為引用型別(Reference Type),可以方便的修改例項及其屬性的值而無需改變型別;而結構體和列舉中的成員均為值型別(Value Type),修改變數的值就相當於修改變數的型別,而Swift預設不允許修改型別,因此需要前置mutating關鍵字用來表示該函式中能夠修改型別 用class實現協議中的mutating方法時,不用寫mutating關鍵字;用結構體,列舉實現協議中的mutating方法時,必須寫mutating關鍵字 6.協議型別 協議本身不實現任何功能,但你可以將它當做型別來使用 使用場景: 作為函式,方法或構造器中的引數型別,返回值型別 作為常量,變數,屬性的型別 作為陣列,字典或其他容器中的元素型別 7.委託(代理)模式 8.在擴充套件中新增協議成員 9.通過擴充套件補充協議宣告:當一個型別已經實現了協議中的所有要求,卻沒有宣告時,可以通過擴充套件來補充協議宣告 10.集合中的協議型別:協議型別可以被集合使用,表示集合中的元素均為協議型別 11.協議的繼承:協議能夠繼承一到多個其他協議。語法與類的繼承相似,多個協議間用逗號,分隔 12.協議合成:一個協議可由多個協議採用protocol<oneProtocol,twoProtocol>這樣的格式進行組合,稱為協議合成(protocol composition)。 13.檢驗協議的一致性 使用is檢驗協議一致性,使用as將協議型別向下轉換(downcast)為的其他協議型別 is操作符用來檢查例項是否遵循了某個協議。 as?返回一個可選值,當例項遵循協議時,返回該協議型別;否則返回nil as用以強制向下轉換型。 @objc用來表示協議是可選的,也可以用來表示暴露給Objective-C的程式碼,此外,@objc型 協議只對類有效,因此只能在類中檢查協議的一致性。 14.可選協議要求 在協議中使用@optional關鍵字作為字首來定義可選成員。 可選協議在呼叫時使用可選鏈 可選協議只能在含有@objc字首的協議中生效。且@objc的協議只能被類遵循。 15.Swift 標準庫中定義了一個Equatable協議,該協議要求任何遵循的型別實現等式符(==)和不等符(!=)對任何兩個該型別進行比較。所有的 Swift 標準型別自動支援Equatable協議
擴充套件extension 1.Swift使用extension宣告擴充套件 2.Swift 中的擴充套件可以: (1)新增計算型屬性和計算靜態屬性: 擴充套件可以新增新的計算屬性,但是不可以新增儲存屬性,也不可以向已有屬性新增屬性觀測器(property observers)。 (2)定義例項方法和型別方法 :擴充套件可以向已有型別新增新的例項方法和型別方法.通過擴充套件新增的例項方法也可以修改該例項本身。結構體和列舉型別中修改self或其屬性的方法必須將該例項方法標註為mutating,正如來自原始實現的修改方法一樣。 (3)提供新的構造器:擴充套件能向類中新增新的便利構造器,但是它們不能向類中新增新的指定構造器或解構函式。指定構造器和解構函式必須總是由原始的類實現來提供。 (4)定義下標:擴充套件可以向一個已有型別新增新下標 (5)定義和使用新的巢狀型別:擴充套件可以向已有的類、結構體和列舉新增新的巢狀型別 (6)使一個已有型別符合某個協議 :一個擴充套件可以擴充套件一個已有型別,使其能夠適配一個或多個協議(protocol)
範型<> 1.Swift使用<>來宣告泛型函式或泛型型別。 2.Swift支援在類、列舉和結構中使用泛型 3.泛型程式碼可以讓你寫出根據自我需求定義、適用於任何型別的,靈活且可重用的函式和型別。它的可以讓你避免重複的程式碼,用一種清晰和抽象的方式來表達程式碼的意圖。 4.泛型函式 func swapTwoValues (inout a: T, inout b: T) {} 佔位型別T是一種型別引數的示例。型別引數指定並命名為一個佔位型別,並且緊隨在函式名後面,使用一對尖括號括起來.可支援多個型別引數,命名在尖括號中,用逗號分開。
型別別名 typealias 1.Swift 使用typealias關鍵字定義型別別名 2. typealias AudioSample = UInt16
斷言assert 1.Swift中用全域性函式assert來斷言除錯2.assert函式接受一個布林表示式和一個斷言失敗時顯示的訊息。如: let age = -3; assert(age >= 0, " age cannot < zero")
取餘運算子 % 1.Swift允許對浮點數執行取餘運算 2. a % b => a = (b × 最多倍數) + 餘數. b為負值時的b的符號被忽略,這意味著%b和%-b的結果是一樣的. 8 % 2.5 = 0.5 ; => (8 = 2.5*3+0.5)
賦值運算子 = Swift中賦值運算子並不將自身作為一個值進行返回,所以以下的程式碼是不合法的: if x = y { // 錯誤, 因為x = y並不會返回一個值 }
字串 String
1.特殊字元
空字元\0,反斜槓\,製表符\t,換行符\n,回車符\r,雙引號\”和單引號\’
單位元組Unicode字元,\xnn,其中nn是兩個十六進位制數
雙位元組Unicode字元,\unnnn,其中nnnn是四個十六進位制數
四位元組Unicode字元,\Unnnnnnnn,其中nnnnnnnn是八個十六進位制數
2. 字串不是指標,而是實際的值
在Swift中,一個String型別就是一個實際的值,當把String a 賦值給 String b或者把String a 傳遞給函式引數,實際相當於建立了一個相等的新值,而不是僅僅像指標那樣指向過去。
var str5: String = "4"
var str6 = str5
str5 = "5"
println(str5) //輸出5
println(str6) //輸出4
3. 用屬性 isEmpty 檢查一個字串是否為空
4. 用全域性函式 countElements 計算字串中字元的數量
5.字串相等:當兩個字串包含的字元完全相同時,被判斷為相等 ==
6. hasPrefix 和 hasSuffix
var str = "ssssssss"
if str.hasPrefix("ssss") {
println("str have prefix ssss")
}
7. uppercaseString 和 lowercaseString
Switch
- 不用寫break,不會自動跳轉到下一case 2.case語句可以匹配多種型別,包括資料範圍,元組,或者特定的型別等 case 1...3: case ( _ , 0 ): // _可以匹配任意值 case ( -2...2 , -2...2 ): case (let x, 0): //數值繫結 case let (x, y) where x == y: //Where關鍵詞
for迴圈 1.for index in 1...5 {} 中index是一個常量,不用對index定義,每次迴圈開始前index都已被賦值 2.for _ in 1...power {} 用_來忽略序列中的值
控制跳轉語句 1.continue : 停止此次迴圈,開始下一次迴圈 2.break : 用來終止迴圈或switch 3.fallthrough : 實現讓switch中執行完一個case跳轉到下一個case 4.return
標籤語句 1.標籤語句的一般形式如下: label name: while condition { statements }
閉包 1.閉包表示式語法 { (parameters) -> return type in statements } 2.閉包和類的強引用 當將一個閉包賦值給一個類例項的屬性,並且閉包體捕獲這個例項時,也可能存在一個強引用迴圈。捕獲例項是因為閉包體訪問了例項的屬性,就像self.someProperty,或者呼叫了例項的方法,就像self.someMethod()。不管哪種情況,這都造成閉包捕獲self,造成強引用迴圈。
閉包 之 Sort函式 let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] // Sort函式 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = sort(names, backwards) // 閉包:-表示式語法 reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } ) // 閉包:-根據上下文推斷型別 reversed = sort(names, { s1, s2 in return s1 > s2 } ) // 閉包:-單行表示式閉包可以省略 return reversed = sort(names, { s1, s2 in s1 > s2 } ) // 閉包:引數名簡寫 reversed = sort(names, { $0 > $1 } ) // 閉包:-運算子函式 reversed = sort(names, >) //閉包: Trailing 閉包 reversed = sort(names) { $0 > $1 }
閉包 之 map函式
- Swift 的 Array 型別有一個 map 方法,其獲取一個閉包表示式作為其唯一引數。陣列中的每一個元素呼叫一次該閉包函式,並返回該元素所對映的值(也可以是不同型別的值)。
- let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 { output = digitNames[number % 10]! + output
number /= 10 }
return output } // 字典 digitNames 下標後跟著一個歎號 (!),因為字典下標返回一個可選值 (optional value),表明即使該 key不存在也不會查詢失敗。 在上例中,它保證了 number % 10 可以總是作為一個 digitNames 字典的有效下標 key。 因此歎號可以用於強展開 (force-unwrap) 儲存在可選下標項中的 String 型別值。
屬性 1.懶惰儲存屬性是當它第一次被使用時才進行初值計算。通過在屬性宣告前加上@lazy來標識一個懶惰儲存屬性。必須宣告懶惰儲存屬性為變數屬性(通過var),因為它的初始值直到例項初始化完成之後才被檢索。常量屬性在例項初始化完成之前就應該被賦值,因此常量屬性不能夠被宣告為懶惰儲存屬性。 2.屬性觀察者 willSet: 引數預設命名 newValue didSet: 引數預設命名 oldValue 屬性初始化時,willset和didSet並不會被呼叫。只有在初始化上下文之外,當設定屬性值時才被呼叫. 3. 例項屬性和型別屬性 對值型別而言,定義型別屬性使用static關鍵字,而定義類型別的型別屬性使用class關鍵字 4.在初始化時修改靜態屬性.當你在設定靜態屬性值時,只要在初始化完成之前,你都可以在初始化時隨時修改靜態屬性。注意:對於類的例項化,一個靜態屬性只能在初始化時被修改,這個初始化在類定義時已經確定。
關鍵字 被保留的關鍵字(keywords)不允許用作識別符號,除非被反引號轉義,參見 識別符號。 用作宣告的關鍵字: class、deinit、enum、extension、func、import、init、let、protocol、static、struct、subscript、typealias、var 用作語句的關鍵字: break、case、continue、default、do、else、fallthrough、if、in、for、return、switch、where、while 用作表達和型別的關鍵字: as、dynamicType、is、new、super、self、Self、Type、COLUMN、FILE、FUNCTION、LINE 特定上下文中被保留的關鍵字: associativity、didSet、get、infix、inout、left、mutating、none、nonmutating、operator、override、postfix、precedence、prefix、right、set、unowned、unowned(safe)、unowned(unsafe)、weak、willSet,這些關鍵字在特定上下文之外可以被用於識別符號。
下標語法 1.使用subscript關鍵字定義 2.subscript(index: Int) -> Int { get { } set(newValue) {} }
自動引用技術 對於生命週期中會變為nil的例項使用弱引用。相反的,對於初始化賦值後再也不會被賦值為nil的例項,使用無主引用。 弱引用必須被宣告為變數,表明其值能在執行時被修改。弱引用不能被宣告為常量。 無主引用是永遠有值的 Swift 有如下要求:只要在閉包內使用self的成員,就要用self.someProperty或者self.someMethod(而不只是someProperty或someMethod)。這提醒你可能會不小心就捕獲了self。
可選鏈 可選鏈可替代強制解析
型別檢查 1.檢查型別 用型別檢查操作符(is)來檢查一個例項是否屬於特定子型別。 if item is SomeClass 2.向下轉型 型別轉型操作符帶有兩種不同形式。可選形式( optional form) as? 返回一個你試圖下轉成的型別的可選值(optional value)。強制形式 as 把試圖向下轉型和強制解包(force-unwraps)結果作為一個混合動作。 3.Any和AnyObject的型別檢查 Swift為不確定型別提供了兩種特殊型別別名: AnyObject可以代表任何class型別的例項。 Any可以表示任何型別,除了方法型別(function types)。