swift變量

1. swift的基本變量類型html

 swift 的變量類型和OC、C基本類似,int = 整形, double = 雙精度浮點 , float = 單精度浮點, string = 字符串, bool = 布爾值,swift

swift中一行結束不須要使用 ; ,可是若是兩句代碼寫到同一行,就須要用 ; 隔開api

2.swift屬性聲明數組

和OC不一樣,swift的屬性分爲變量和常量,用let 聲明常量,用var聲明變量,常量的值不可更改。安全

屬性註釋服務器

  1. var welcomeMessage: String 

如上代碼, : 表示的是屬性類型,上面聲明的是一個 String類型的變量,變量名是welcomeMessage 數據結構

welcomeMessage只能賦值爲字符串。app

也能夠定義多個相同類型的屬性,中間用逗號隔開less

  1. var red, green, blue: Double

如上,定義了三個 Double類型的變量。ide

swift有變量類型推導,因此基本上不用定義類型,好比

      var text = 10   

這時text就是int類型的。

變量名能夠包括任意字符,甚至Unicode,和漢語,常量和變量名稱不能包含空白字符,數學符號,箭頭,專用(或無效)Unicode代碼點或線條和框圖字符。也不能以數字開頭,儘管數字可能包含在名字的其餘地方。

一旦聲明瞭某個類型的常量或變量,就不能再聲明它的名字,或者改變它來存儲不一樣類型的值。你也不能把一個常量變成一個變量或一個常量變量。

 

打印函數爲Print()

print(_:separator:terminator:)函數是一個全局函數,它將一個或多個值打印到適當的輸出。例如,在Xcode中,該print(_:separator:terminator:)函數在Xcode的「控制檯」窗格中輸出其輸出。separatorterminator參數都有默認值,因此當你調用這個函數,你能夠忽略它們。默認狀況下,函數經過添加換行符來終止打印的行。要打印一個沒有換行符的值,傳遞一個空字符串做爲終止符 - 例如print(someValue, terminator: "")

 

Swift使用字符串插值將常量或變量的名稱做爲佔位符包含在較長的字符串中,並提示Swift將其替換爲該常量或變量的當前值。用圓括號將名稱包裝起來,並在左括號以前用反斜槓進行轉義:

  1. print("The current value of friendlyWelcome is \(friendlyWelcome)")
  2. // Prints "The current value of friendlyWelcome is Bonjour!"

注意

你能夠用串插中使用的全部選項中描述字符串插值

註釋

使用註釋在代碼中包含不可執行的文本,做爲註釋或提醒。在編譯代碼時,Swift編譯器會忽略註釋。

Swift中的註釋與C中的註釋很是類似。單行註釋以兩個正斜槓(//開頭

  1. // This is a comment.

多行註釋以正斜槓開始,後跟星號(/*),以星號結尾,後跟正斜槓(*/):

  1. /* This is also a comment
  2. but is written over multiple lines. */

與C中的多行註釋不一樣,Swift中的多行註釋能夠嵌套在其餘多行註釋中。您能夠經過啓動多行註釋塊,而後在第一個塊內開始第二個多行註釋來編寫嵌套註釋。而後關閉第二個塊,而後關閉第一個塊:

  1. /* This is the start of the first multiline comment.
  2. /* This is the second, nested multiline comment. */
  3. This is the end of the first multiline comment. */

嵌套的多行註釋使您可以快速輕鬆地註釋大量代碼,即便代碼已經包含多行註釋。

分號

與許多其餘語言不一樣,Swift不須要;在代碼中的每一個語句以後都寫一個分號(),儘管若是你願意的話能夠這樣作。可是,若是要在一行中編寫多個單獨的語句須要使用分號

  1. let cat = "🐱"; print(cat)
  2. // Prints "🐱"

整型

整數是沒有小數部分的整數,如42-23整數有符號(正數,零或負數)或無符號數(正數或零)。

Swift提供了8,16,32和64位格式的有符號和無符號整數。這些整數遵循相似於C的命名約定,其中8位無符號整數是類型的UInt8,32位有符號整數是類型的Int32像Swift中的全部類型同樣,這些整數類型都有大寫的名字。

整數界限

你能夠用它來訪問每一個整數類型的最小值和最大值minmax特性:

  1. let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
  2. let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8

這些屬性的值是適當大小的數字類型(UInt8例如上面的示例中),所以能夠在表達式中與其餘相同類型的值一塊兒使用。

詮釋

在大多數狀況下,您不須要選擇要在代碼中使用的特定大小的整數。Swift提供了一個額外的整數類型,Int它與當前平臺的本地字大小大小相同:

  • 在一個32位平臺上,Int尺寸與Int32

  • 在64位平臺上,Int尺寸與Int64

除非須要使用特定大小的整數,不然請Int在代碼中使用整數值。這有助於代碼的一致性和互操做性。即便在32位平臺上,Int也能夠存儲-2,147,483,648之間的任意值2,147,483,647,而且對於不少整數範圍來講足夠大。

UINT

Swift還提供了一個無符號整數類型,UInt它的大小與當前平臺的本地字大小相同:

  • 在一個32位平臺上,UInt尺寸與UInt32

  • 在64位平臺上,UInt尺寸與UInt64

注意

UInt僅在您特別須要與平臺的本機字大小相同的無符號整數類型時才使用若是不是這種狀況,Int即便要知道存儲的值是非負的也是優選的。Int整數值的一導致用有助於代碼的互操做性,避免了在不一樣數字類型之間進行轉換的須要,並匹配整數類型推斷,如類型安全和類型推斷中所述

浮點數字

浮點數是具備小數部分的數字,例如3.141590.1,和-273.15

浮點類型能夠表示比整數類型更普遍的數值範圍,而且能夠存儲比能夠存儲在數組中更大或更小的數字IntSwift提供了兩個有符號的浮點數類型:

  • Double 表明一個64位的浮點數。

  • Float 表示一個32位的浮點數。

注意

Double具備至少15位十進制數的精度,而精度Float能夠小至6位十進制數。要使用適當的浮點類型取決於您須要在代碼中使用的值的性質和範圍。在任何類型都適合的狀況下,Double是首選。

類型安全和類型推斷

Swift是一個類型安全的語言。類型安全的語言鼓勵你清楚你的代碼可使用的值的類型。若是你的代碼的一部分須要一個String,你不能Int錯誤地經過它

由於Swift是類型安全的,因此它在編譯代碼時執行類型檢查,並將任何不匹配的類型標記爲錯誤。這使您可以在開發過程當中儘早捕獲並修復錯誤。

類型檢查有助於避免在使用不一樣類型的值時發生錯誤。可是,這並不意味着你必須指定你聲明的每一個常量和變量的類型。若是你不指定你須要的值的類型,Swift使用類型推斷來計算出適當的類型。類型推斷使編譯器可以在編譯代碼時自動推斷特定表達式的類型,只需檢查您提供的值便可。

因爲類型推理,與C或Objective-C等語言相比,Swift所需的類型聲明要少得多。常量和變量仍然是明確的類型,可是不少指定類型的工做都是爲你完成的。

當你用一個初始值聲明一個常量或變量時,類型推斷特別有用。這一般是經過在聲明它的點處爲常量或變量賦予一個文字值(或文字)來完成的。(A字面值是直接出如今源代碼中,如一個值423.14159在下面的例子。)

例如,若是你將一個42新的常量賦值給一個新的常量,而沒有說明它是什麼類型的話,那麼Swift推斷你想讓這個常量成爲一個常量Int,由於你用一個看起來像一個整數的數字來初始化它:

  1. let meaningOfLife = 42
  2. // meaningOfLife is inferred to be of type Int

一樣,若是你沒有爲浮點數指定一個類型,Swift會推斷你想建立一個Double

  1. let pi = 3.14159
  2. // pi is inferred to be of type Double

當推斷浮點數的類型時, Swift老是選擇Double(而不是Float)。

若是在表達式中結合整數和浮點文字,Double將從上下文中推斷出一種類型

  1. let anotherPi = 3 + 0.14159
  2. // anotherPi is also inferred to be of type Double

字面值3沒有明確的類型自己,因此Double從浮點文字的存在推斷出適當的輸出類型做爲加法的一部分。

數字文字

整數文字能夠寫成:

  • 一個十進制數,沒有前綴

  • 一個二進制數字,帶有0b前綴

  • 一個八進制數,有0o前綴

  • 一個十六進制數,有0x前綴

全部這些整數文字都有一個十進制值17

  1. let decimalInteger = 17
  2. let binaryInteger = 0b10001 // 17 in binary notation
  3. let octalInteger = 0o21 // 17 in octal notation
  4. let hexadecimalInteger = 0x11 // 17 in hexadecimal notation

浮點文字能夠是十進制(不帶前綴)或十六進制(帶0x前綴)。它們必須在小數點的兩側始終有一個數字(或十六進制數字)。十進制浮點數也能夠有一個可選的指數,用大寫或小寫表示e十六進制浮點數必須有一個指數,用大寫或小寫表示p

對於指數爲的十進制數exp,基數乘以10 exp

  • 1.25e2意味着1.25 x 10 2,或125.0

  • 1.25e-2意味着1.25 x 10 -2,或者0.0125

對於指數爲的十六進制數exp,基數乘以2 exp

  • 0xFp2指15 x 2 2,或60.0

  • 0xFp-2指的是15 x 2 -2,或者3.75

全部這些浮點文字都有十進制值12.1875

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

數字文字能夠包含額外的格式,以方便閱讀。整數和浮點數均可以用額外的零填充,而且能夠包含下劃線來幫助提升可讀性。這兩種格式都不影響字面值的基礎值:

  1. let paddedDouble = 000123.456
  2. let oneMillion = 1_000_000
  3. let justOverOneMillion = 1_000_000.000_000_1

數字類型轉換

Int在代碼中 使用全部通用整數常量和變量類型,即便它們已知是非負的。在平常狀況下使用默認的整數類型意味着整型常量和變量能夠在您的代碼中當即互操做,而且將與整型文字值的推斷類型相匹配。

僅當手頭任務特別須要使用其餘整數類型時,才能使用其餘整數類型,這是由於來自外部源的顯式大小的數據,或性能,內存使用狀況或其餘必要的優化。在這些狀況下使用明確大小的類型有助於捕獲任何意外的值溢出,並隱含地記錄正在使用的數據的性質。

整數轉換

能夠存儲在整數常量或變量中的數字範圍對於每種數字類型都是不一樣的。一個Int8常數或變量能夠存儲之間的數字-128127,而UInt8常數或變量能夠存儲之間的數字0255在編譯代碼時,不能將其放入常量或變量的大小的整數類型中會報告爲錯誤:

  1. let cannotBeNegative: UInt8 = -1
  2. // UInt8 cannot store negative numbers, and so this will report an error
  3. let tooBig: Int8 = Int8.max + 1
  4. // Int8 cannot store a number larger than its maximum value,
  5. // and so this will also report an error

因爲每種數字類型均可以存儲不一樣範圍的值,所以您必須逐個選擇數字類型轉換。這種選擇加入方法能夠防止隱藏的轉換錯誤,並有助於在代碼中明確類型轉換意圖。

要將一個特定的號碼類型轉換爲另外一個號碼類型,您須要使用現有的值初始化一個所需類型的新號碼。在下面的例子中,常量twoThousand是類型的UInt16,而常量one是類型的UInt8他們不能直接加在一塊兒,由於他們不是同一類型的。相反,這個例子調用UInt16(one)建立一個新UInt16one,並用這個值代替原來的值:

  1. let twoThousand: UInt16 = 2_000
  2. let one: UInt8 = 1
  3. let twoThousandAndOne = twoThousand + UInt16(one)

由於添加的兩邊都是如今的類型UInt16,因此容許添加。輸出常量(twoThousandAndOne)被推斷爲是類型的UInt16,由於它是兩個UInt16的總和

SomeType(ofInitialValue)是調用Swift類型的初始值設定項並傳入初始值的默認方式。在幕後,UInt16有一個接受一個UInt8的初始化器,因此這個初始化器被用來UInt16從現有的一個新UInt8你不能在這裏傳入任何類型,可是它必須是一個UInt16提供初始化的類型擴展示有類型以提供接受新類型(包括您本身的類型定義)的初始化方法在擴展中介紹

整數和浮點轉換

整數和浮點數字類型之間的轉換必須明確:

  1. let three = 3
  2. let pointOneFourOneFiveNine = 0.14159
  3. let pi = Double(three) + pointOneFourOneFiveNine
  4. // pi equals 3.14159, and is inferred to be of type Double

在這裏,常量的值three被用來建立一個新的類型值Double,因此添加的兩邊是相同的類型。若是沒有這個轉換,不容許增長。

浮點到整數轉換也必須明確。整數類型可使用DoubleFloat來初始化

  1. let integerPi = Int(pi)
  2. // integerPi equals 3, and is inferred to be of type Int

當用這種方式初始化一個新的整數值時,浮點值老是被截斷的。這意味着4.75變成4-3.9變成-3

注意

數字常量和變量的組合規則與數字文字的規則不一樣。字面值3能夠直接添加到文字值0.14159,由於數字文字自己沒有明確的類型。只有在編譯器評估它們的時候才推斷它們的類型。

類型別名

類型別名爲現有類型定義了一個替代名稱。您可使用typealias關鍵字定義類型別名

若是要經過上下文更合適的名稱引用現有類型,例如在從外部源處理特定大小的數據時,類型別名頗有用:

  1. typealias AudioSample = UInt16

一旦你定義了一個類型別名,你能夠在任何你可能使用原始名稱的地方使用別名:

  1. var maxAmplitudeFound = AudioSample.min
  2. // maxAmplitudeFound is now 0

這裏AudioSample被定義爲一個別名UInt16由於它是一個別名,AudioSample.min實際調用的調用UInt16.min,它提供0maxAmplitudeFound變量的初始值

布爾

Swift有一個基本的布爾類型,叫作Bool布爾值被稱爲邏輯,由於它們只能是真或假。Swift提供了兩個布爾常量值,true而且false

  1. let orangesAreOrange = true
  2. let turnipsAreDelicious = false

根據它們用布爾文字值初始化的事實推斷了這些類型orangesAreOrangeturnipsAreDelicious已經被推斷出來Bool正如IntDouble上面,你並不須要聲明常量或變量Bool,若是將其設置爲truefalse爲您建立它們儘快。類型推斷有助於使Swift代碼在使用其餘已知類型的值初始化常量或變量時更加簡潔易讀。

當您使用條件語句(如if語句)時,布爾值特別有用

  1. if turnipsAreDelicious {
  2. print("Mmm, tasty turnips!")
  3. } else {
  4. print("Eww, turnips are horrible.")
  5. }
  6. // Prints "Eww, turnips are horrible."

控制流程if中更詳細地介紹了 諸如聲明等條件語句

Swift的類型安全性能夠防止非布爾值被替換Bool如下示例報告編譯時錯誤:

  1. let i = 1
  2. if i {
  3. // this example will not compile, and will report an error
  4. }

可是,下面的替代示例是有效的:

  1. let i = 1
  2. if i == 1 {
  3. // this example will compile successfully
  4. }

i == 1比較 的結果是類型的Bool,因此這個第二個例子經過類型檢查。比較像i == 1基本操做符中討論

就像Swift中的其餘類型安全例子同樣,這種方法避免了意外錯誤,並確保特定代碼段的意圖老是清晰的。

元組

組將多個值組合爲一個複合值。元組中的值能夠是任何類型,沒必要是彼此相同的類型。

在這個例子中,(404, "Not Found")是一個描述HTTP狀態碼的元組每當您請求網頁時,HTTP狀態碼都是由Web服務器返回的特殊值。404 Not Found若是您請求不存在的網頁,則會返回狀態代碼

  1. let http404Error = (404, "Not Found")
  2. // http404Error is of type (Int, String), and equals (404, "Not Found")

這個(404, "Not Found")元組將an Int和a 分組在一塊兒String,爲HTTP狀態碼提供了兩個獨立的值:一個數字和一我的類可讀的描述。它能夠被描述爲「一個類型的元組(Int, String)」。

你能夠從任何類型的排列中建立元組,而且能夠包含儘量多的不一樣類型。沒有什麼阻止你有型的元組(Int, Int, Int),或者(String, Bool),或者你確實須要的任何其餘排列。

你能夠一個元組的內容分解成單獨的常量或變量,而後像往常同樣訪問:

  1. let (statusCode, statusMessage) = http404Error
  2. print("The status code is \(statusCode)")
  3. // Prints "The status code is 404"
  4. print("The status message is \(statusMessage)")
  5. // Prints "The status message is Not Found"

若是您只須要某些元組的值,則_在分解元組時,請使用下劃線(忽略部分元組:

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

或者,使用從零開始的索引號訪問元組中的各個元素值:

  1. print("The status code is \(http404Error.0)")
  2. // Prints "The status code is 404"
  3. print("The status message is \(http404Error.1)")
  4. // Prints "The status message is Not Found"

當定義元組時,能夠將元組中的各個元素命名爲:

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

若是您將元素命名爲元組,則可使用元素名稱來訪問這些元素的值:

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

元組做爲函數的返回值特別有用。嘗試檢索網頁的函數可能會返回(Int, String)元組類型來描述頁面檢索的成功或失敗。經過返回具備兩個不一樣類型的值的元組,每一個不一樣類型的函數都提供了有關其結果的更多有用信息,而不是僅返回單個類型的單個值。有關更多信息,請參閱具備多個返回值的函數

注意

元組對於相關值的臨時組是有用的。它們不適合建立複雜的數據結構。若是您的數據結構可能會持續超出臨時範圍,則將其建模爲類或結構,而不是元組。有關更多信息,請參閱類和結構

選配

在價值可能不存在的狀況下 使用可選項可選的表明兩種可能性:要麼有一個值,你能夠解開可選的訪問值,或者有沒有價值可言。

注意

C或Objective-C中不存在可選項的概念。Objective-C中最接近的東西是nil從一個方法返回的能力,不然返回一個對象,nil意思是「缺乏一個有效的對象」。可是,這隻適用於對象 - 它不適用於結構,基本C類型或枚舉值。對於這些類型,Objective-C方法一般會返回一個特殊值(如NSNotFound)來指示缺乏值。這種方法假設方法的調用者知道有一個特殊的值來測試,並記得檢查它。Swift的選項可讓你指出沒有任何類型的值,而不須要特殊的常量。

如下是如何使用可選項來應對價值缺失的一個例子。Swift的Int類型有一個初始化器,它試圖將一個String值轉換成一個Int值。可是,並非每一個字符串均可以轉換成一個整數。該字符串"123"能夠轉換爲數字值123,但字符串"hello, world"沒有明顯的數值轉換。

下面的例子使用初始化器來嘗試將a String轉換爲Int

  1. let possibleNumber = "123"
  2. let convertedNumber = Int(possibleNumber)
  3. // convertedNumber is inferred to be of type "Int?", or "optional Int"

由於初始化器可能失敗,因此它返回一個可選的 Int,而不是一個Int可選Int是寫成Int?,而不是Int問號表示它所包含的值是可選的,這意味着它可能包含一些 Int值,或者它可能根本不包含任何值(它不能包含任何其餘的東西,好比Bool值或String值,它能夠是一個Int,或者什麼也不是。)

經過給可選變量賦予一個特殊值來設置一個可選變量nil

  1. var serverResponseCode: Int? = 404
  2. // serverResponseCode contains an actual Int value of 404
  3. serverResponseCode = nil
  4. // serverResponseCode now contains no value

注意

你不能使用nilnonoptional常量和變量。若是代碼中的某個常量或變量須要在某些條件下沒有值的狀況下工做,則始終將其聲明爲適當類型的可選值。

若是您定義了一個可選變量而不提供默認值,則會自動nil爲您設置該變量

  1. var surveyAnswer: String?
  2. // surveyAnswer is automatically set to nil

注意

Swift nilnilObjective-C 不同在Objective-C中,nil是一個指向不存在對象的指針。在Swift中,nil不是一個指針,而是缺乏某種類型的值。選配的任何類型能夠設置爲nil,不僅是對象類型。

若是陳述和強制解包

您可使用if語句經過比較可選的against來肯定可選是否包含值nil您使用「等於」運算符(==)或「不等於」運算符(!=執行此比較

若是可選值有一個值,則認爲它是「不等於」 nil

  1. if convertedNumber != nil {
  2. print("convertedNumber contains some integer value.")
  3. }
  4. // Prints "convertedNumber contains some integer value."

一旦肯定可選的確實包含一個值,就能夠經過!在可選名稱的末尾添加一個感嘆號()來訪問其基礎值感嘆號有效地說:「我知道這個可選確定有價值,請使用它「。這被稱爲強制展開可選的值:

  1. if convertedNumber != nil {
  2. print("convertedNumber has an integer value of \(convertedNumber!).")
  3. }
  4. // Prints "convertedNumber has an integer value of 123."

有關詳情if,請參閱控制流程

注意

嘗試使用!訪問不存在的可選值觸發運行時錯誤。nil在使用!強制解開其值以前,請確保可選包含非值。

可選的綁定

您使用可選綁定來查找可選是否包含值,若是是,則使該值可用做臨時常量或變量。可選的綁定能夠ifwith while語句一塊兒用來檢查一個可選的值,並把這個值提取到一個常量或變量中,做爲單個動做的一部分。ifwhile控制流程中更詳細地描述報表

if語句編寫一個可選的綁定,以下所示:

  • 若是 constantName = someOptional {
  •     聲明
  • }

您能夠重寫Optionals部分中possibleNumber示例以使用可選綁定而不是強制展開:

  1. if let actualNumber = Int(possibleNumber) {
  2. print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
  3. } else {
  4. print("\"\(possibleNumber)\" could not be converted to an integer")
  5. }
  6. // Prints ""123" has an integer value of 123"

這段代碼能夠讀做:

「若是Int返回的可選Int(possibleNumber)值包含一個值,則設置一個新的常量調用actualNumber可選值中包含的值。」

若是轉換成功,則該actualNumber常量在if語句的第一個分支內可用它已經被包含可選項中的值初始化,因此不須要使用!後綴來訪問它的值。在這個例子中,actualNumber只是用來打印轉換的結果。

您可使用可選綁定的常量和變量。若是您想操做語句actualNumber第一個分支內的值if,您能夠if var actualNumber改成寫入,而且可選內容中的值將做爲變量而不是常量提供。

您能夠根據須要在單個if語句中包含儘量多的可選綁定和布爾條件,並用逗號分隔。若是可選綁定中的nil任何值或任何布爾條件的計算結果false,則整個if語句的條件被認爲是false如下if聲明是等同的:

  1. if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
  2. print("\(firstNumber) < \(secondNumber) < 100")
  3. }
  4. // Prints "4 < 42 < 100"
  5. if let firstNumber = Int("4") {
  6. if let secondNumber = Int("42") {
  7. if firstNumber < secondNumber && secondNumber < 100 {
  8. print("\(firstNumber) < \(secondNumber) < 100")
  9. }
  10. }
  11. }
  12. // Prints "4 < 42 < 100"

注意

if語句中使用可選綁定建立的常量和變量只能在if語句的主體中使用相反,使用guard語句建立的常量和變量能夠在語句以後的代碼行中找到guard,如Early Exit中所述

隱含解包選項

如上所述,可選項表示常數或變量被容許具備「無值」。可使用if語句來檢查選項,以查看是否存在值,而且可使用可選綁定有條件地解包,以訪問可選值(若是存在)。

有時從程序的結構中能夠清楚地看到,在第一次設置值以後,可選項將始終有一個值。在這些狀況下,每次訪問時都不須要檢查和打開可選的值,由於能夠安全地假定全部的時間都有一個值。

這些選項被定義爲隱含的解包選項你寫一個隱式解開的可選項,在你想要的可選類型以後放置一個感嘆號(String!)而不是一個問號(String?)。

當一個可選的值被確認在第一次定義的可選值以後當即存在時,隱式解包的可選值是有用的,而且能夠確定地假定在隨後的每一個點都存在。Swift中隱式解包選項的主要用途是在類初始化期間,如Unowned References和Unwinedly Unwrapped Optional Properties中所述

隱式解包可選是幕後的普通可選項,但也能夠像非可選值同樣使用,而沒必要在每次訪問時展開可選值。如下示例顯示了在以可顯式方式訪問包裝值時,可選字符串與隱式解包的可選字符串之間的行爲差​​異String

  1. let possibleString: String? = "An optional string."
  2. let forcedString: String = possibleString! // requires an exclamation mark
  3. let assumedString: String! = "An implicitly unwrapped optional string."
  4. let implicitString: String = assumedString // no need for an exclamation mark

你能夠想象一個隱式解包的可選方法,只要使用它就能夠自動解包這個可選方法。每次使用時,不要在可選名稱後面放置感嘆號,而是在聲明它時在可選類型後面放置感嘆號。

注意

若是隱式解包可選,nil而且您嘗試訪問其包裝的值,則會觸發運行時錯誤。結果與在不包含值的普通可選項以後放置感嘆號徹底相同。

你仍然能夠像一個普通的可選項那樣對待一個隱式的解包可選,來檢查它是否包含一個值:

  1. if assumedString != nil {
  2. print(assumedString)
  3. }
  4. // Prints "An implicitly unwrapped optional string."

你也可使用一個帶有可選綁定的隱式解包可選方法,在一個語句中檢查和解包它的值:

  1. if let definiteString = assumedString {
  2. print(definiteString)
  3. }
  4. // Prints "An implicitly unwrapped optional string."

注意

當變量有可能nil在稍後出現時,不要使用隱式解包的可選項若是您須要nil在變量的生命週期中檢查,請始終使用正常的可選類型

錯誤處理

您可使用錯誤處理來響應您的程序在執行過程當中可能遇到的錯誤狀況。

與可選擇性有關,它可使用值的存在或不存在來傳遞函數的成功或失敗,錯誤處理容許您肯定失敗的根本緣由,而且,若是有必要,將錯誤傳播到程序的另外一部分。

當一個函數遇到一個錯誤條件時,它會拋出一個錯誤。而後該函數的調用者能夠捕獲錯誤並做出適當的響應。

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

一個函數指示它能夠經過throws在其聲明中包含關鍵字來引起錯誤當你調用一個可能引起錯誤的函數時,你try須要在表達式中加上關鍵字。

Swift自動將錯誤從當前做用域傳出,直到它們被一個catch子句處理

  1. do {
  2. try canThrowAnError()
  3. // no error was thrown
  4. } catch {
  5. // an error was thrown
  6. }

一個do語句建立一個新的包含範圍,它容許錯誤傳播到一個或多個catch子句。

如下是錯誤處理如何用於響應不一樣錯誤條件的示例:

  1. func makeASandwich() throws {
  2. // ...
  3. }
  4. do {
  5. try makeASandwich()
  6. eatASandwich()
  7. } catch SandwichError.outOfCleanDishes {
  8. washDishes()
  9. } catch SandwichError.missingIngredients(let ingredients) {
  10. buyGroceries(ingredients)
  11. }

在這個例子中,makeASandwich()若是沒有可用的乾淨的菜餚,或者若是有任何配料丟失,該功能將會報錯。由於makeASandwich()能夠拋出一個錯誤,函數調用被包裝在一個try表達式中。經過將函數調用包裝在一個do語句中,拋出的任何錯誤都會傳播到提供的catch子句中。

若是沒有錯誤,eatASandwich()則調用函數。若是拋出一個錯誤,並匹配SandwichError.outOfCleanDishes大小寫,那麼washDishes()函數將被調用。若是拋出一個錯誤而且匹配SandwichError.missingIngredients大小寫,那麼該buyGroceries(_:)函數將被調用,並[String]使用catch模式捕獲的相關

錯誤處理中 詳細介紹了拋出,捕獲和傳播錯誤

斷言和先決條件

斷言先決條件是在運行時發生的檢查。在執行任何進一步的代碼以前,使用它們來確保知足基本條件。若是斷言或前提條件中的布爾條件評估爲true,則代碼執行將像往常同樣繼續。若是條件評估爲false,程序的當前狀態是無效的; 代碼執行結束,你的應用程序被終止。

您使用斷言和先決條件來表達您所作的假設以及編碼時的指望,這樣您就能夠將它們包含在代碼中。斷言有助於您在開發過程當中發現錯誤和不正確的假設,而且先決條件可幫助您檢測生產中的問題。

除了在運行時驗證您的指望外,斷言和先決條件也成爲代碼中有用的文檔形式。與上述錯誤處理中討論的錯誤條件不一樣,斷言和先決條件不用於可恢復或預期的錯誤。由於失敗的斷言或先決條件代表一個無效的程序狀態,沒有辦法遇上失敗的斷言。

使用斷言和先決條件不能替代設計代碼的方式,以致於不可能出現無效條件。可是,使用它們強制執行有效的數據和狀態會致使您的應用程序在發生無效狀態時更可預測地終止,並有助於使問題更易於調試。一旦檢測到無效狀態,當即中止執行也有助於限制由該無效狀態形成的損害。

斷言和先決條件之間的區別在於它們被檢查時:只在調試版本中檢查斷言,可是在調試版本和生產版本中檢查前提條件。在生產構建中,斷言內的條件不被評估。這意味着您能夠在開發過程當中使用盡量多的斷言,而不會影響生產性能。

用斷言進行調試

你能夠經過調用assert(_:_:file:line:)Swift標準庫中函數來編寫斷言若是條件的結果是,則將此函數傳遞給計算結果爲trueor 的表達式,false並顯示要顯示的消息false例如:

  1. let age = -3
  2. assert(age >= 0, "A person's age can't be less than zero.")
  3. // This assertion fails because -3 is not >= 0.

在這個例子中,若是age >= 0計算true結果是代碼執行繼續,也就是說,若是值age是非負的。若是age上面的代碼中的值爲負數,則age >= 0評估爲false,而且斷言失敗,則終止該應用程序。

你能夠省略斷言信息 - 例如,當它只是重複做爲散文的條件。

  1. assert(age >= 0)

若是代碼已經檢查了條件,則使用該assertionFailure(_:file:line:)函數來指示斷言失敗。例如:

  1. if age > 10 {
  2. print("You can ride the roller-coaster or the ferris wheel.")
  3. } else if age > 0 {
  4. print("You can ride the ferris wheel.")
  5. } else {
  6. assertionFailure("A person's age can't be less than zero.")
  7. }

執行先決條件

當條件有多是錯誤的時候使用前提條件,可是對於代碼繼續執行確定是正確的。例如,使用前提條件來檢查下標是否超出範圍,或檢查函數是否已傳遞有效值。

你經過調用precondition(_:_:file:line:)函數來編寫一個前提條件若是條件的結果是,則將此函數傳遞給計算結果爲trueor 的表達式,false並顯示要顯示的消息false例如:

  1. // In the implementation of a subscript...
  2. precondition(index > 0, "Index must be greater than zero.")

您也能夠調用該preconditionFailure(_:file:line:)函數來指示發生了故障 - 例如,若是採起了開關的默認狀況,但全部有效的輸入數據都應由交換機的其餘狀況之一處理。

注意

若是以非檢查模式編譯(-Ounchecked),則不檢查前置條件。編譯器假定前置條件老是正確的,並相應地優化了你的代碼。可是,fatalError(_:file:line:)不管優化設置如何,該函數都會暫停執行。

您能夠fatalError(_:file:line:)在原型開發和早期開發中使用該函數,經過編寫fatalError("Unimplemented")存根實現來建立還沒有實現的功能的存根。因爲致命錯誤永遠不會被優化,與斷言或前提條件不一樣,您能夠確保執行始終中止,若是遇到存根實現。

(原文地址) https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309

相關文章
相關標籤/搜索