在iOS 10 和微信小程序的大浪潮下,Swift 3 卻少有人提及,前不久,iOS開發(fā)者翹首以盼的Swift 3終于來了, 就像很多人預(yù)測的一樣,Swift 3的API基本趨于穩(wěn)定,不會(huì)像以前一樣改動(dòng)的太大,讓你無從下手,此時(shí)是最好的學(xué)習(xí)機(jī)會(huì)。盡管以前學(xué)習(xí)過部分,但決定重新梳理一下,從頭開始,不積跬步無以至千里。入門學(xué)習(xí)資料,應(yīng)該沒有比官方更靠譜的吧。The Swift Programming Language (Swift 3)
- 1 . 常量
let
如果你的代碼存儲(chǔ)的值不會(huì)改變,用
let
關(guān)鍵字聲明為常量。let聲明的值是不會(huì)再改變的,再次賦值會(huì)編譯不過
let maximumNumberOfLoginAttempts = 10
- 2 . 變量
var
聲明變量的關(guān)鍵值,如果你代碼中的值需要改變,請(qǐng)用
var
關(guān)鍵字聲明為變量。
var currentLoginAttempt = 0
- 3 . 打印
print()
和OC中的
NSLog()
類似,print("打印這個(gè)值 \\\\(值)")
。
- 4 .分號(hào)
;
不像許多其他語言,Swift并不要求你寫一個(gè)分號(hào)(;代碼中的每個(gè)語句后),當(dāng)然你也可以這樣做。然而,分號(hào)在Swift中的用法是如果你想要在一行上寫多個(gè)獨(dú)立的語句時(shí)需要:
let cat = ""; print(cat)
- 5 .整數(shù)
整數(shù)全是數(shù)字,沒有小數(shù)部分,如42和-23。整數(shù)有符號(hào)類型(正,零或負(fù)的)或無符號(hào)類型(正或零)。Swift在8,16,32位和64位的形式提供有符號(hào)和無符號(hào)整數(shù)。這些整數(shù)遵循類似于C的命名約定,在一個(gè)8位的無符號(hào)整數(shù)的類型為UInt8,一個(gè)32位帶符號(hào)整數(shù)的類型為Int32。
- 5.1 .整數(shù)邊界
可以訪問整數(shù)類型的最小值和最大值min與max屬性:
let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8
- 5.2 .INT類型
在大多數(shù)情況下,你不需要挑整數(shù)的特定大小在代碼中使用。Int,其具有的范圍與當(dāng)前平臺(tái)的位數(shù)相同:
在32位的平臺(tái)上,Int其大小與相同Int32。
在64位的平臺(tái)上,Int其大小與相同Int64。
除非你有特殊的要求去限制整數(shù)的值,不然就不用特殊設(shè)置范圍。在32位平臺(tái)上,Int可以是-2,147,483,648和2,147,483,647的任意值,滿足大多數(shù)要求,所以官方推薦直接使用Int,不自己區(qū)分位數(shù)。
- 5.3 .UINT類型
與INT類型一致,只是無符號(hào)類型而已,不能表達(dá)負(fù)數(shù)。官方推薦使用Int
- 6 .浮點(diǎn)型
Double,Float
浮點(diǎn)數(shù)是具有小數(shù)部分的數(shù)字,例如3.14159,0.1,和-273.15。在未聲明類型時(shí),Swift默認(rèn)為Double.
Double 代表一個(gè)64位浮點(diǎn)數(shù)。
Float 表示32位浮點(diǎn)數(shù)。
6.0.png
- 7 .類型安全和類型推斷
Swift是一個(gè)類型安全的語言。類型安全的語言可以讓你清楚地知道代碼要處理的值的類型。如果你的代碼的一部分需要一個(gè)String,你傳遞一個(gè)Int會(huì)直接報(bào)錯(cuò)。因?yàn)樗鼤?huì)在編譯你的代碼時(shí)進(jìn)行類型檢查,并把不匹配的類型標(biāo)記為錯(cuò)誤。這可以讓你在開發(fā)的時(shí)候盡早發(fā)現(xiàn)并修復(fù)錯(cuò)誤。
7.0.png
let meaningOfLife = 42 //類型推斷為int
let pi = 3.14159 //類型推斷為double
let anotherPi = 3 + 0.14159 //類型推斷為double
- 8 . 數(shù)字表示
十進(jìn)制數(shù),沒有前綴
let decimalInteger = 17
二進(jìn)制數(shù),用0b前綴let binaryInteger = 0b10001
八進(jìn)制數(shù),有0o前綴let octalInteger = 0o21
十六進(jìn)制數(shù),用0x前綴let hexadecimalInteger = 0x11
當(dāng)然你也可以這樣寫let oneMillion = 1_000_000
和let oneMillion = 1000000
等價(jià)
- 9 .數(shù)字類型轉(zhuǎn)換
在Swift中不同類型的數(shù)字不能直接運(yùn)算,在編譯期就會(huì)提示錯(cuò)誤信息給你,防止隱藏的轉(zhuǎn)換錯(cuò)誤
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
錯(cuò)誤示例:let twoThousandAndOne = twoThousand + one
正確寫法:let twoThousandAndOne = twoThousand + UInt16(one)
let three = 3
let pointOneFourOneFiveNine = 0.14159
錯(cuò)誤示例:let pi = three + pointOneFourOneFiveNine
正確寫法: let pi = Double(three) + pointOneFourOneFiveNine
- 10 .類型別名
typealias
類型別名即給現(xiàn)有的類型起個(gè)別的名字。關(guān)鍵字為typealias。
typealias AudioSample = UInt16 //給UInt16起個(gè)別名AudioSample
var maxAmplitudeFound = AudioSample.min //AudioSample.min等價(jià)于UInt16.min。
- 11.布爾值
true
false
提供了兩個(gè)布爾常量值,true和false,如果你在需要使用 Bool 類型的地方使用了非布爾值,Swift 的類型安全機(jī)制會(huì)報(bào)錯(cuò)。
11.0.png
但是你可以這樣寫,i == 1 的比較結(jié)果是 Bool 類型,可以通過類型檢查
let i = 1
if i == 1 {
// this example will compile successfully
}
- 12 .元組
元組做的事情就是把多個(gè)值組合成一個(gè)復(fù)合值。元組內(nèi)的值可以是任意類型,并不要求是相同類型。和OC中的數(shù)組類似
- 12.1 組合
你可以把任意順序的類型組合成一個(gè)元組,這個(gè)元組可以包含所有類型。只要你想,你可以創(chuàng)建一個(gè)類型為 (Int, Int, Int) 或者 (String, Bool) 或者其他任何你想要的組合的元組。
let http404Error = (404, "Not Found")
// http404Error 的類型是 (Int, String),值是 (404, "Not Found")
- 12.2 分解
你可以將一個(gè)元組的內(nèi)容分解(decompose)成單獨(dú)的常量和變量,然后你就可以正常使用它們了
let (statusCode, statusMessage) = http404Error
print("The status code is \\\\(statusCode)")
// 輸出 "The status code is 404"
print("The status message is \\\\(statusMessage)")
// 輸出 "The status message is Not Found"
- 12.3 忽略
如果你只需要一部分元組值,分解的時(shí)候可以把要忽略的部分用下劃線(_)標(biāo)記:
let (justTheStatusCode, _) = http404Error
print("The status code is \\\\(justTheStatusCode)")
// 輸出 "The status code is 404"
- 12.4 下標(biāo)訪問
此外,你還可以通過下標(biāo)來訪問元組中的單個(gè)元素,下標(biāo)從零開始:
print("The status code is \\\\(http404Error.0)")
// 輸出 "The status code is 404"
print("The status message is \\\\(http404Error.1)")
// 輸出 "The status message is Not Found"
- 12.5 命名獲取
你可以在定義元組的時(shí)候給單個(gè)元素命名,給元組中的元素命名后,你可以通過名字來獲取這些元素的值:
let http200Status = (statusCode: 200, description: "OK")
print("The status code is \\\\(http200Status.statusCode)")
// 輸出 "The status code is 200"
print("The status message is \\\\(http200Status.description)")
// 輸出 "The status message is OK"
可變?cè)媸强梢再x值的,但在賦值時(shí),可變?cè)M雖然可以修改數(shù)據(jù),但卻不能改變其數(shù)據(jù)的數(shù)據(jù)類型:如下
- 13 .可選類型
optionals
C 和 Objective-C 中并沒有可選類型這個(gè)概念。最接近的是 Objective-C 中的一個(gè)特性,一個(gè)方法要么返回一個(gè)對(duì)象要么返回nil,nil表示“缺少一個(gè)合法的對(duì)象”。然而,這只對(duì)對(duì)象起作用——對(duì)于結(jié)構(gòu)體,基本的 C 類型或者枚舉類型不起作用。對(duì)于這些類型,Objective-C 方法一般會(huì)返回一個(gè)特殊值(比如NSNotFound)來暗示值缺失。這種方法假設(shè)方法的調(diào)用者知道并記得對(duì)特殊值進(jìn)行判斷。然而,Swift 的可選類型可以讓你暗示任意類型的值缺失,并不需要一個(gè)特殊值。
來看一個(gè)例子。Swift 的 Int 類型有一種構(gòu)造器,作用是將一個(gè) String 值轉(zhuǎn)換成一個(gè) Int 值。然而,并不是所有的字符串都可以轉(zhuǎn)換成一個(gè)整數(shù)。字符串 "123" 可以被轉(zhuǎn)換成數(shù)字 123 ,但是字符串 "hello, world" 不行。下面的例子使用這種構(gòu)造器來嘗試將一個(gè) String 轉(zhuǎn)換成 Int:
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推測為類型 "Int?", 或者類型 "optional Int"
- 14 .nil
Swift 的 nil 和 Objective-C 中的 nil 并不一樣。在 Objective-C 中,nil 是一個(gè)指向不存在對(duì)象的指針。在 Swift 中,nil 不是指針——它是一個(gè)確定的值,用來表示值缺失。任何類型的可選狀態(tài)都可以被設(shè)置為 nil,不只是對(duì)象類型。
- 14.1 賦值
你可以給可選變量賦值為nil來表示它沒有值,但nil不能用于非可選的常量和變量。
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value
- 14.2 聲明
如果你聲明一個(gè)可選常量或者變量但是沒有賦值,它們會(huì)自動(dòng)被設(shè)置為 nil:
var surveyAnswer: String?
// surveyAnswer is automatically set to nil
- 15 .if 語句以及強(qiáng)制解析
你可以使用 if 語句和 nil 比較,來判斷一個(gè)可選值是否包含值。你可以使用“相等”(==)或“不等”(!=)來執(zhí)行比較。
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// Prints "convertedNumber contains some integer value."
當(dāng)你確定可選類型確實(shí)包含值之后,你可以在可選的名字后面加一個(gè)感嘆號(hào)(!)來獲取值。這個(gè)驚嘆號(hào)表示你知道這個(gè)可選有值,稱為可選值的強(qiáng)制解析(官方文檔的forced unwrapping):
if convertedNumber != nil {
print("convertedNumber has an integer value of \\\\(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."
- 16 . 可選綁定
optional binding
使用可選綁定來判斷可選類型是否包含值,如果包含就把值賦給一個(gè)臨時(shí)常量或者變量。可選綁定可以用在 if 和 while 語句中,這種用法不僅可以用來判斷可選類型中是否有值,同時(shí)可以將可選類型中的值賦給一個(gè)常量或者變量。
if let constantName = someOptional {
statements
}
使用可選綁定來重寫 possibleNumber
if let actualNumber = Int(possibleNumber) {
print("\\\\"\\\\(possibleNumber)\\\\" has an integer value of \\\\(actualNumber)")
} else {
print("\\\\"\\\\(possibleNumber)\\\\" could not be converted to an integer")
}
解讀:如果Int(possibleNumber)
返回的可選 Int 包含一個(gè)值,就創(chuàng)建一個(gè)叫做 actualNumber
的新常量并將可選包含的值賦給它。
如果轉(zhuǎn)換成功,actualNumber
常量可以在 if 語句的第一個(gè)分支中使用。它已經(jīng)被可選類型 包含的 值初始化過,所以不需要再使用 ! 后綴來獲取它的值。在這個(gè)例子中,actualNumber
只被用來輸出轉(zhuǎn)換結(jié)果。
你可以在可選綁定中使用常量和變量。如果你想在if語句的第一個(gè)分支中操作 actualNumber
的值,你可以改成if var actualNumbe
r,這樣可選類型包含的值就會(huì)被賦給一個(gè)變量而非常量。
- 17 .隱式解析可選類型
implicitly unwrapped optionals
如上所述,可選類型暗示了常量或者變量可以“沒有值”。可選可以通過 if 語句來判斷是否有值,如果有值的話可以通過可選綁定來解析值。
有時(shí)候在程序架構(gòu)中,第一次被賦值之后,可以確定一個(gè)可選類型總會(huì)有值。在這種情況下,每次都要判斷和解析可選值是非常低效的,因?yàn)榭梢源_定它總會(huì)有值。這種類型的可選狀態(tài)被定義為隱式解析可選類型。把想要用作可選類型的后面的問號(hào)(String?)改成感嘆號(hào)(String!)來聲明一個(gè)隱式解析可選類型。
當(dāng)可選類型被第一次賦值之后就可以確定之后一直有值的時(shí)候,隱式解析可選類型非常有用。隱式解析可選類型主要被用在 Swift 中類的構(gòu)造過程中。一個(gè)隱式解析可選類型其實(shí)就是一個(gè)普通的可選類型,但是可以被當(dāng)做非可選類型來使用,并不需要每次都使用解析來獲取可選值。下面的例子展示了可選類型 String 和隱式解析可選類型 String 之間的區(qū)別:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
/*****下面是隱式解析可選類型 String *****/
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark
如果你在隱式解析可選類型沒有值的時(shí)候嘗試取值,會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤。和你在沒有值的普通可選類型后面加一個(gè)驚嘆號(hào)一樣。
所以你可以把隱式解析可選類型當(dāng)做普通可選類型來判斷它是否包含值:
if assumedString != nil {
print(assumedString)
}
// Prints "An implicitly unwrapped optional string."
你也可以在可選綁定中使用隱式解析可選類型來檢查并解析它的值:
if let definiteString = assumedString {
print(definiteString)
}
// Prints "An implicitly unwrapped optional string."
如果一個(gè)變量之后可能變成nil的話請(qǐng)不要使用隱式解析可選類型。如果你需要在變量的生命周期中判斷是否是nil的話,請(qǐng)使用普通可選類型。
可選類型 | 解讀
----|------|----
普通可選類型 | 可選類型可以讓你暗示任意類型的值缺失,并不需要一個(gè)特殊值。當(dāng)你不確定你所賦予的那個(gè)值時(shí),就用(String?)即 (類型?)。
隱式解析可選類型 | 在第一次被賦值之后,可以確定一個(gè)可選類型總會(huì)有值,把想要用作可選類型的后面的問號(hào)(String?)改成感嘆號(hào)(String!)來聲明一個(gè)隱式解析可選類型。本質(zhì)是普通可選類型,只是當(dāng)做當(dāng)做非可選類型來使用。
- 17 .斷言
assert()
可選類型可以讓你判斷值是否存在,你可以在代碼中處理值缺失的情況。然而,在某些情況下,如果值缺失或者值并不滿足特定的條件,你的代碼可能沒辦法繼續(xù)執(zhí)行。這時(shí),你可以在你的代碼中觸發(fā)一個(gè) 斷言 來結(jié)束代碼運(yùn)行并通過調(diào)試來找到值缺失的原因。給你一個(gè)代碼調(diào)試工具 ,看個(gè)人喜好使用。不滿足條件時(shí)會(huì)斷點(diǎn)打印,會(huì)定位到具體錯(cuò)誤行數(shù),僅為DEBUG模式。
17.0.png
控制臺(tái)需要斷言信息
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// this causes the assertion to trigger, because age is not >= 0
控制臺(tái)不需要斷言信息
let age = -3
assert(age >= 0)
以上只是一些簡單的概念說(fan)明(yi),如有錯(cuò)誤請(qǐng)指正,謝謝。Swift 3 學(xué)習(xí) ,后續(xù)會(huì)不斷更新。
如果你覺得我的文章對(duì)你有幫助請(qǐng)點(diǎn)喜歡哦,也可以關(guān)注我,每周至少一篇技術(shù)更新。
或者關(guān)注 我的專題 每周至少5篇高質(zhì)量文章收錄,多謝支持。
一起學(xué)習(xí),一起進(jìn)步。