Swift3.0基礎(chǔ)部分(The Basics)(二)

類型安全和類型推斷(Type Safety and Type Inference)
  • Swift是一個類型安全的語言肖油,所以會在編譯的時候會檢查類型不匹配的錯誤。這么做可以盡可能早的在開發(fā)過程中發(fā)現(xiàn)錯誤反镇。
  • 類型檢查幫助避免在不同類型的值的錯誤奋蔚。雖然這樣,但也不意味著必須把每個變量(常量)的類型寫出來联贩。因?yàn)镾wift使用類型推斷來給出合適的類型漫仆。
let meaningOfLife = 42
//meaningOfLife is inferred to be of type Int

當(dāng)不聲明一個浮點(diǎn)型時,默認(rèn)是Double類型泪幌。

let pi = 3.14159
//pi is inferred to be of type Double
let anotherPi = 3 + 0.14159
//anotherPi is also inferred to be of type Double
數(shù)字型的字面值(Numeric Literals)
  • 整型的字面可以這么寫:
    • 十進(jìn)制:不需要前綴
    • 二進(jìn)制:前綴為"0b"
    • 八進(jìn)制:前綴為"0o"
    • 十六進(jìn)制:前綴為"0x"

以下這些的值都是17

let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInteger = 0x11
  • 浮點(diǎn)型的字面可以為十進(jìn)制(沒有前綴)盲厌,也可以為十六進(jìn)制(前綴為"0x")。十進(jìn)制數(shù)用大寫或者小寫的e表示指數(shù)祸泪,十六進(jìn)制數(shù)用大寫或小寫的p表示指數(shù)吗浩。
    十進(jìn)制:

    • 1.25e2 means 1.25 x 10^2, or 125.0.
    • 1.25e-2 means 1.25 x 10^(-2), or 0.0125.

    十六進(jìn)制:

    • 0xFp2 means 15 x 2^2, or 60.0.
    • 0xFp-2 means 15 x 2^(-2), or 3.75.

    下面這些浮點(diǎn)型的值都是12.1875

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

numeric literals為了更好的閱讀代碼可以包含額外的格式,整型和浮點(diǎn)型都可以使用前綴"0"和下劃線"_"

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
數(shù)值類型的轉(zhuǎn)換(Numeric Type Conversion)#
  • 整型的轉(zhuǎn)換(Integer Conversion)
    當(dāng)然没隘,整形的存儲是不能超過類型的范圍的懂扼,那UInt8(0255)和Int8(-128127)為例:
let cannotBeNegative: UInt8 = -1
//UInt8 cannot store negative numbers, and so this will report an error.
let tooBig: Int8 = Int8.max + 1
//Int8 cannot store a number larger than its maximum value,
//and so this will also report an error

當(dāng)兩種數(shù)值不是一個類型的時候是不能進(jìn)行運(yùn)算的,哪怕他們都是“整型”:

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let towThousandAndOne = twoThousand + UInt16(one)
//swift的強(qiáng)制轉(zhuǎn)換和OC是不同的升略,swift是將類型放在括號外面微王,而將變量(常量)放在括號里面。
  • 整型和浮點(diǎn)型之間的相互轉(zhuǎn)換(Integer and Floating-Point Conversion)
    在整型和浮點(diǎn)型之間轉(zhuǎn)換一定要明確:
let three = 3
let pointOneFourOneFiveNine = 0.141459
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double
類型的別稱(Type Aliases)

類型的重命名用到的是"typealias"關(guān)鍵字品嚣。

typealias AudioSample = UInt16
//correct
let max: AudioSample = AudioSample.max
//wrong
let max: AudioSample = UInt16.max
布爾型(Boolean)

Swift中的布爾型與C語言和OC都不一樣炕倘,為"Bool",而其值和C語言是一直的翰撑,分別為"true"和"false"罩旋。
因?yàn)閠ype safety的緣故啊央,下面的代碼是錯誤的

let i = 1
if i {
    //this example will not compile, and will repot an error
}

所以,這段代碼應(yīng)該這么寫:

let i = 1
if i == 1 {
    //this example will compile successfully
}

因?yàn)?i == 1"的返回值是Bool涨醋,所以這段代碼可以執(zhí)行瓜饥。

元組(Tuples)

元組就是一組多個值合成為一個單一的值,而這一組的多個值并不是一定要相同的類型浴骂。
??:

let http404Error = (404, "Not Found")
//http404Error is of type (Int, String)

你可以在創(chuàng)建一個元組的時候任意的排序類型乓土。
你也可以在定義一個元組的時候,將類型分離溯警,??:

let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
//Prints "The status code is 404"

如果你只需要為元組中的某個元素命名是趣苏,其他的可以用下劃線(_)代替:

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Prints "The status code is 404"

你也可以通過訪問元組的索引值來訪問相應(yīng)的元素:

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK"

在定義一個元組的時候,就可以為每個元素命名梯轻,這樣就可以直接通過元素名稱來訪問:

let http200Status = (statusCode: 200, description: "OK")

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK"
可選變量(Optionals)#

在C語言和OC中是沒有optionals的概念的食磕,但在OC中有一個類似的類型就是NSNil。Optionals通俗點(diǎn)講喳挑,就是這個值可能存在彬伦,也可能不存在。舉個??:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"
  • nil
    在聲明一個變量的時候可以分配一個特殊的值——nil:
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value

在聲明一個可選變量的時候不賦給初始值伊诵,默認(rèn)為nil(數(shù)值類型的值同樣為nil)单绑。

  • 可選綁定(Optional Binding)
    可選綁定,如果一個可選變量的值不為nil曹宴,則將值賦給另外一個變量(常量)询张。可選綁定可以用在if和while的判斷條件中浙炼。??:
if let actualNumber = Int(possibleNumber) {
        print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
        print("\"\(possibleNumber)\" could not be converted to an integer")
}
// Prints ""123" has an integer value of 123"

你可以在一個if判斷條件中包含多個可選綁定和"where"子句來進(jìn)行判斷,如果其中有任意一個可選綁定為空(nil)唯袄,或者"where"的返回值為"false"弯屈,整個可選綁定都會不成功:

if let firstNumber = Int("4"), secondNumber = Int("42") where irstNumber < secondNumber {
        print("\(firstNumber) < \(secondNumber)")
}
// Prints "4 < 42"
  • 隱式解析可選類型(Implicitly Unwrapped Optional)(也不知道是不是叫這個名字)
    有些變量在聲明的時候就已經(jīng)有值了,如果還是每次都判斷是否為空就會非常低效恋拷,所以就有了這個Implicity Unwrapped Optional類型资厉,意思就是我聲明的這個變量不為空,用感嘆號表示(!)蔬顾。
    下面這個??展示了Optionals和Implicity Unwrapped Optional的區(qū)別:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

同樣的宴偿,你可以判斷隱式解析可選類型是否為空(nil),也可以進(jìn)行可選綁定诀豁。
??:

if assumedString != nil {
    print(assumedString)
}
// Prints "An implicitly unwrapped optional string."
if let definiteString = assumedString {
    print(definiteString)
}
// Prints "An implicitly unwrapped optional string."
異常處理(Error Handling)

當(dāng)一個方法遇到錯誤情況窄刘,它就會拋出(throws)一個錯誤。而方法的調(diào)用者就會捕捉(catch)到錯誤信息舷胜,并及時處理娩践。

func canThrowAnError() throws {
    //this function may or may not throw an error
}

當(dāng)一個方法可以拋出錯誤的時候在它聲明方法名的時候要包括"throws"關(guān)鍵字。當(dāng)你調(diào)用一個可以拋出錯誤的方法時,在前面用"try"關(guān)鍵字來修飾翻伺。
Swift會自動將錯誤信息從當(dāng)先這個范圍傳遞出去材泄,知道會遇到"catch"子句的時候才會進(jìn)行處理。

do {
    try canThrowAnError()
    //no error was thrown
} catch {
    //an error was thrown
}

"do"狀態(tài)創(chuàng)建了一個新的可以允許錯誤信息傳遞給一個或者多個"catch"子句的包含范圍吨岭。
??:

func makeASandwich() throws {
// ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

上面這個??中拉宗,"makeASandewich()"將會在沒有干凈盤子的時候執(zhí)行"washDishes()"。之所以"makeASandwich()"可以拋出一個錯誤辣辫,是因?yàn)檫@個方法包含了"try"表達(dá)式旦事。如果沒有錯誤拋出,那么"eatASandwich()"這個方法就會執(zhí)行络它。

  • 斷言(Assertions)
    在某些情況下族檬,如果一個特定的條件不滿足,那么代碼就不會繼續(xù)執(zhí)行化戳。在這些情況下单料,你可以在你的代碼中設(shè)置一個斷言(asserttion)來結(jié)束代碼的執(zhí)行或者提供一個調(diào)試值為空或者不存在的機(jī)會。

    • 用斷言進(jìn)行調(diào)試(Debug with Assertions)
      assertion會在runtime檢查一個Boolean表達(dá)式的值是否為true点楼。字面的意思就是扫尖,一個assertion"斷言"一個表達(dá)式是否為真。如果表達(dá)式的值為true掠廓,那么代碼會照常執(zhí)行换怖,如果表達(dá)式的值為false,代碼執(zhí)行結(jié)束蟀瞧,app會直接終止沉颂。
      但你在調(diào)試情況下使用assertions,可以附加一條自己的信息悦污。在Swift標(biāo)準(zhǔn)庫中铸屉,調(diào)用"assert(::file:line:)"方法,這是一個全球變量:
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

assertions的信息也可以省略切端。

assert(age >= 0)
  • 什么時候使用斷言(When to Use Assertions)
    使用assertions首先要確保表達(dá)是的值有可能為false彻坛,但是想要代碼繼續(xù)執(zhí)行的話,值一定為true踏枣。以下幾種情況適用assertions:
    • 一個整數(shù)下標(biāo)索引值傳到了一個自定義的下標(biāo)實(shí)現(xiàn)昌屉,而值超出了范圍(太小或太大)。
    • 給函數(shù)傳入一個值茵瀑,但是非法的值可能導(dǎo)致函數(shù)不能正常執(zhí)行间驮。
    • 一個可選值現(xiàn)在為nil,但是代碼需要一個不為nil的值才能成功執(zhí)行马昨。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜻牢,一起剝皮案震驚了整個濱河市烤咧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抢呆,老刑警劉巖煮嫌,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抱虐,居然都是意外死亡昌阿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門恳邀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懦冰,“玉大人,你說我怎么就攤上這事谣沸∷⒏郑” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵乳附,是天一觀的道長内地。 經(jīng)常有香客問我,道長赋除,這世上最難降的妖魔是什么阱缓? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮举农,結(jié)果婚禮上荆针,老公的妹妹穿的比我還像新娘。我一直安慰自己颁糟,他們只是感情好航背,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棱貌,像睡著了一般沃粗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上键畴,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音突雪,去河邊找鬼起惕。 笑死,一個胖子當(dāng)著我的面吹牛咏删,可吹牛的內(nèi)容都是我干的惹想。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼督函,長吁一口氣:“原來是場噩夢啊……” “哼嘀粱!你這毒婦竟也來了激挪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤锋叨,失蹤者是張志新(化名)和其女友劉穎垄分,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娃磺,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薄湿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了偷卧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豺瘤。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖听诸,靈堂內(nèi)的尸體忽然破棺而出坐求,到底是詐尸還是另有隱情,我是刑警寧澤晌梨,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布桥嗤,位于F島的核電站,受9級特大地震影響派任,放射性物質(zhì)發(fā)生泄漏砸逊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一掌逛、第九天 我趴在偏房一處隱蔽的房頂上張望师逸。 院中可真熱鬧,春花似錦豆混、人聲如沸篓像。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽员辩。三九已至,卻和暖如春鸵鸥,著一層夾襖步出監(jiān)牢的瞬間奠滑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工妒穴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宋税,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓讼油,卻偏偏與公主長得像杰赛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子矮台,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容