元組
- 定義: 可以將多個(gè)不同類型的值合成單個(gè)復(fù)合值桥爽。(可以是任意類型的)
- 使用:
-
可以將內(nèi)容分為常量或變量進(jìn)行常規(guī)訪問:
let https = (404,"Not Found") let (statusCode, statusMessage) = https print("The status code is \(statusCode)") //輸出:The status code is 404
-
如只需某些元組的值,可以用“_”來忽略元組的部分值
let (value , _ ) = https print("The status code is \(value)") //輸出:The status code is 404
-
使用從0開始索引訪問元組各個(gè)元素值或給元組各個(gè)元素命名來訪問
let examples = (a:200,b:"OK") print("The value is \(examples.0)") //輸出:The value is 200 print("The value is \(examples.a)") //輸出:The value is 200
-
適用:
- 作為函數(shù)的返回值特別有用
- 互換值:(a,b)= (b,a) 等
-
可選類型
- 定義:可能不存在值的數(shù)據(jù)類型底洗。兩種可能:要么是有一個(gè)值踩蔚,你可以解開可選的訪問值,或者是沒有價(jià)值可言,為nil隙姿。
- 注意: Object-C和swift中的nil不同:OC中是一個(gè)指向不存在對象的指針,只適用于對象(引用)類型厂捞,不適用與值類型输玷。swift中nil不是一個(gè)指針,它是沒有某種類型的值靡馁,任何類型的可選項(xiàng)都可以設(shè)置為nil欲鹏,而不僅僅是對象類型。
- 使用:
如果你的代碼中的常量或者變量在某些情況下缺少值時(shí)使用臭墨,則始終將其聲明為適當(dāng)類型的可選值赔嚎。(可選類型默認(rèn)值:nil)
-
一般展開可選類型的寫法
if 可選類型名 != nil { print("It must have a value \(可選類型名!) ") }
-
安全展開可選類型的寫法(可選綁定:來確定可選項(xiàng)是否包含值,如果是,則將值用作臨時(shí)常量或變量尤误。否則走else)
if let newValue = 可選類型名 { print("It must have a value \(newValue) ") } 重點(diǎn):可以包含多個(gè)(let newValue = 可選類型名),中間用“,”隔開侠畔,只要其中一個(gè)為nil則整個(gè)表達(dá)式都為否。
可以使用感嘆號來訪問其基礎(chǔ)值(注:一旦使用袄膏!訪問践图,必須保證一定存在值,否則將error)
??:進(jìn)行解包沉馆,如果包含值則返回本身码党,否則返回默認(rèn)值。a ?? b <==> a != nil ? a! : b
- 隱式解析可選類型
-
定義后綴
!
作為標(biāo)準(zhǔn)庫中命名類型Optional<Wrapped>
的語法糖斥黑,來實(shí)現(xiàn)自動解包的功能var implicitlyUnwrappedString: String! var explicitlyUnwrappedString: Optional<String>
-
注意:由于隱式解包修改了包含器類型的聲明語義揖盘,嵌套在元組類型或泛型的可選類型(比如字典元素類型或數(shù)組元素類型),不能被標(biāo)記為隱式解包锌奴。
let tupleOfImplicitlyUnwrappedElements: (Int!, Int!) // 錯(cuò)誤 let implicitlyUnwrappedTuple: (Int, Int)! // 正確 let arrayOfImplicitlyUnwrappedElements: [Int!] // 錯(cuò)誤 let implicitlyUnwrappedArray: [Int]! // 正確
-
元類型
- 定義: 元類型是指類型的類型兽狭,包括類類型、結(jié)構(gòu)體類型鹿蜀、枚舉類型和協(xié)議類型箕慧。
- 獲取元類型:類、結(jié)構(gòu)體或枚舉類型的元類型是相應(yīng)的類型名緊跟
.Type
茴恰。協(xié)議類型的元類型——并不是運(yùn)行時(shí)符合該協(xié)議的具體類型——而是該協(xié)議名字緊跟.Protocol
颠焦。比如,類SomeClass
的元類型就是SomeClass.Type
往枣,協(xié)議SomeProtocol
的元類型就是SomeProtocal.Protocol
伐庭。 - 類型名.self來獲取類型。也可以使用
type(of:)
來獲取該實(shí)例在運(yùn)行期的類型分冈。
使用goard的正確姿勢
-
可以用goard:在驗(yàn)證入口條件時(shí)
func refreshData() { let session = Int("12") goard let value = session else {reture} print("\(session!)") } 好處: 1.一眼看出圾另,這個(gè)條件檢查并不是函數(shù)本身的功用,而是函數(shù)執(zhí)行的先決條件雕沉。 2.如果有人不小心將提前退出的語句從 else 表達(dá)式中移除了集乔,編譯器會及時(shí)告訴你這個(gè)錯(cuò)誤。
使用場景:方法中存在非常長的執(zhí)行路徑坡椒,在最終結(jié)果得到之前扰路,中間會有多個(gè)需要被滿足的條件,這些條件都應(yīng)該為真肠牲,否則應(yīng)該直接 return 或者拋出異常幼衰。(這些條件可以用guard拋出)
-
可以用 guard:在可選值解包時(shí)(拍扁 if let..else 金字塔):使用 guard 的方式來解包可選值是非常推薦的。if let 的方式需要在大括號內(nèi)使用解包之后的值缀雳,而 guard 語句將解包之后的值添加到了之后的作用域之中——所以你可以在使用 guard 解包之后直接使用它渡嚣,不用包裹在大括號內(nèi)。
guard let id = json["id"] as? Int, let name = json["name"] as? String, let userId = json["user_id"] as? Int, let position = json["pos"] as? Double else { throw ParsingError.MissingData } return Task(id: id, name: name, userId: userId, position: position)
錯(cuò)誤處理
-
可以使用值得存在或不存在來傳達(dá)函數(shù)的成功或失敗,錯(cuò)誤處理允許您確定故障的根本原因识椰,如有必要绝葡,將錯(cuò)誤傳播到程序的一部分。
如:throws關(guān)鍵字來引發(fā)錯(cuò)誤 func canThrowAnError() throws { } 使用:當(dāng)調(diào)用此函數(shù)時(shí)腹鹉,需要使用如下方式藏畅,并加上try關(guān)鍵字,catch可以是多個(gè) do { try canThrowAnError() } catch { }
斷言和前提條件
- 定義:斷言和前提條件是在運(yùn)行時(shí)發(fā)生的檢查功咒。在執(zhí)行任何其他代碼之前愉阎,您可以使用它們確保滿足基本條件。如果斷言或前提條件中的布爾條件評估為true力奋,則代碼執(zhí)行情況依然如常榜旦。如果條件求值false,程序的當(dāng)前狀態(tài)無效; 代碼執(zhí)行結(jié)束景殷,您的應(yīng)用程序已終止
- 使用:
- assert(age >= 0, "A person's age can't be less than zero."): 當(dāng)條件為false就會拋出error錯(cuò)誤信息溅呢,
- precondition(index > 0, "Index must be greater than zero.") :同上
- assertionFailure("A person's age can't be less than zero."):當(dāng)已經(jīng)檢查了某條件時(shí),可以直接吃用此方法拋出錯(cuò)誤
- preconditionFailure("A person's age can't be less than zero."):同上
基本運(yùn)算符
a...b :全封閉區(qū)間猿挚,相當(dāng)于[a,b]咐旧;
a..<b: 半開半閉區(qū)間,相當(dāng)于[a,b)绩蜻;
-
單面范圍: [a...]铣墨,[...b],[..<b],
for name in names[2...] { //從下標(biāo)2開始到最后 print(name) } for name in names[...2] { //從下標(biāo)0到下標(biāo)2的所有元素 print(name) }
字符串與字符
-
如果需要一個(gè)跨多行的字符串,請使用多行字符串文字 - 由三個(gè)雙引號包圍的一系列字符辜羊。
如:let example = """ The first row The sencond Row ... """
-
使用”+“來拼接兩個(gè)字符串踏兜。
//實(shí)例 let badStart = """ one two """ let end = """ three """ print(badStart + end) // Prints two lines: // one // twothree let goodStart = """ one two """ print(goodStart + end) // Prints three lines: // one // two // three
可以使用”()“進(jìn)行插入值词顾。
-
使用index(before:)and index(after:)方法訪問給定索引之前和之后的索引String八秃。要訪問遠(yuǎn)離給定索引的索引,您可以使用該index(_:offsetBy:)方法肉盹,而不是多次調(diào)用其中一個(gè)方法昔驱。
let greeting = "Guten Tag!" greeting[greeting.startIndex] // G greeting[greeting.index(before: greeting.endIndex)] // ! greeting[greeting.index(after: greeting.startIndex)] // u let index = greeting.index(greeting.startIndex, offsetBy: 7) greeting[index] // a 注意:endIndex是最后一個(gè)字符的下一個(gè)字符的索引,greeting[greeting.endIndex] // Error
-
使用該indices屬性訪問字符串中單個(gè)字符的所有索引上忍。
for index in greeting.indices { print("\(greeting[index]) ", terminator: "") } // Prints "G u t e n T a g ! " 注意: terminator:關(guān)鍵字表示不換行骤肛。
-
插入和刪除(都是索引值,切記不是整數(shù)):
- 要將單個(gè)字符插入到指定索引的字符串中窍蓝,請使用該insert(_:at:)方法腋颠,并在指定的索引處插入另一個(gè)字符串的內(nèi)容,然后使用該insert(contentsOf:at:)方法吓笙。
- 要從指定索引的字符串中刪除單個(gè)字符淑玫,請使用該remove(at:)方法,并刪除指定范圍內(nèi)的子字符串,請使用以下removeSubrange(_:)方法:
比較字符串: ”==“絮蒿,(Swift中的字符串和字符比較不區(qū)分大小寫尊搬。)
前綴和后綴:要檢查字符串是否具有特定的字符串前綴或后綴,請調(diào)用字符串hasPrefix("字符串")和 hasSuffix("字符串")方法
-
UTF-8土涝、UTF-16和Unicode表示字符串
for codeUnit in dogString.utf8 { print("\(codeUnit) ", terminator: "") } print("") // Prints "68 111 103 226 128 188 240 159 144 182 " for codeUnit in dogString.utf16 { print("\(codeUnit) ", terminator: "") } print("") // Prints "68 111 103 8252 55357 56374 " for scalar in dogString.unicodeScalars { print("\(scalar.value) ", terminator: "") } print("") // Prints "68 111 103 8252 128054 " for scalar in dogString.unicodeScalars { print("\(scalar) ", terminator: "") } //Prints "D o g !! "
集合類型
-
數(shù)組遍歷:
定義:var someInts = [Int]() var threeDoubles = Array(repeating: 0.0, count: 3) // threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0] var shoppingList: [String] = ["Eggs", "Milk"] for (index, value) in shoppingList.enumerated() { print("Item \(index + 1): \(value)") } // Item 1: Six eggs // Item 2: Milk // Item 3: Flour // Item 4: Baking Powder // Item 5: Bananas
集合:
-
定義:
var letters = Set<Character>() or var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
- 使用該intersection(_:)方法創(chuàng)建一個(gè)僅具有兩個(gè)集合通用值的新集合佛寿。
- 使用該symmetricDifference(_:)方法創(chuàng)建一個(gè)新集合,其中的值可以是任一集但壮,但不能同時(shí)使用冀泻。
- 使用該union(_:)方法創(chuàng)建一個(gè)新集合,其中所有值都在兩個(gè)集合中蜡饵。
- 使用該subtracting(_:)方法創(chuàng)建一個(gè)新集合腔长,其值不在指定的集合中。
- 使用“等于”運(yùn)算符(==)來確定兩個(gè)集合是否包含所有相同的值验残。
- 使用該isSubset(of:)方法確定集合的所有值是否包含在指定的集合中捞附。
- 使用該isSuperset(of:)方法來確定集合是否包含指定集合中的所有值。
- 使用isStrictSubset(of:)或isStrictSuperset(of:)方法來確定集合是子集還是超集您没,但不等于指定集鸟召。
- 使用該isDisjoint(with:)方法來確定兩個(gè)集合是否沒有共同的值。
字典:
-
定義:
var namesOfIntegers = [Int: String]() // namesOfIntegers is an empty [Int: String] dictionary var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
-
遍歷
for (airportCode, airportName) in airports { print("\(airportCode): \(airportName)") } // YYZ: Toronto Pearson // LHR: London Heathrow 等價(jià)于下面: for airportCode in airports.keys { print("Airport code: \(airportCode)") } // Airport code: YYZ // Airport code: LHR for airportName in airports.values { print("Airport name: \(airportName)") } // Airport name: Toronto Pearson // Airport name: London Heathrow
-
新的遍歷方式:
使用該stride(from:to:by:)功能跳過不需要的標(biāo)記氨鹏。 let minuteInterval = 5 for tickMark in stride(from: 0, to: minutes, by: minuteInterval) { // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55) } 也可以使用閉合范圍stride(from:through:by:): let hours = 12 let hourInterval = 3 for tickMark in stride(from: 3, through: hours, by: hourInterval) { // render the tick mark every 3 hours (3, 6, 9, 12) }