IOS開發語言Swift入門連載---基礎部分

來源:互聯網
上載者:User

IOS開發語言Swift入門連載---基礎部分

 Swift >是 > iOS > 和 >OS X >應用開發的一門新語言。然而,如果你有 > C > 或者 > Objective-C > 開發經驗的話,你會發現>Swift >的很多內容都是你熟悉的。
  Swift >的類型是在 >C >和 >Objective-C> 的基礎上提出的,Int 是整型;Double 和Float 是浮點型;Bool 是布爾型;String 是字串。Swift 還有兩個有用的集合類型,Array 和Dictionary ,請參考集合類型。
  就像 >C >語言一樣,>Swift> 使用變數來進行儲存並通過變數名來關聯值。在 >Swift> 中,值不可變的變數有著廣泛的應用,它們就是常量,而且比 C 語言的常量更強大。在> Swift> 中,如果你要處理的值不需要改變,那使用常量可以讓你的代碼更加安全並且更好地表達你的意圖。
  除了我們熟悉的類型,Swift> 還增加了 >Objective-C> 中沒有的類型比如元組(Tuple)。元組可以讓你建立或者傳遞一組資料,比如作為函數的傳回值時,你可以用一個元組可以返回多個值。
  Swift >還增加了可選(Optional)類型,用於處理值缺失的情況。可選表示“那兒有一個值,並且它等於 >x >”或者“那兒沒有值”。可選有點像在 >Objective-C> 中使用nil ,但是它可以用在任何類型上,不僅僅是類。可選類型比 >Objective-C> 中的nil 指標更加安全也更具表現力,它是 >Swift >許多強大特性的重要組成部分。
  Swift >是一個型別安全的語言,可選就是一個很好的例子。Swift> 可以讓你清楚地知道值的類型。如果你的代碼期望得到一個String ,型別安全會阻止你不小心傳入一個Int 。你可以在開發階段儘早發現並修正錯誤。
  

常量和變數

  常量和變數把一個名字(比如maximumNumberOfLoginAttempts 或者welcomeMessage )和一個指定類型的值(比如數字10 或者字串”Hello” )關聯起來。常量的值一旦設定就不能改變,而變數的值可以隨意更改。
  聲明常量和變數
  常量和變數必須在使用前聲明,用let 來聲明常量,用var 來聲明變數。下面的例子展示了如何用常量和變數來記錄使用者嘗試登入的次數:

let maximumNumberOfLoginAttempts = 10var currentLoginAttempt = 0

  這兩行代碼可以被理解為:
  “聲明一個名字是maximumNumberOfLoginAttempts 的新常量,並給它一個值10 。然後,聲明一個名字是currentLoginAttempt 的變數並將它的值初始化為0 .”
  在這個例子中,允許的最大嘗試登入次數被聲明為一個常量,因為這個值不會改變。當前嘗試登入次數被聲明為一個變數,因為每次嘗試登入失敗的時候都需要增加這個值。
  你可以在一行中聲明多個常量或者多個變數,用逗號隔開:

var x = 0.0, y = 0.0, z = 0.0

  注意:
  如果你的代碼中有不需要改變的值,請使用let 關鍵字將它聲明為常量。只將需要改變的值聲明為變數。
  

類型標註

  當你聲明常量或者變數的時候可以加上類型標註(type annotation),說明常量或者變數中要儲存的值的類型。如果要添加類型標註,需要在常量或者變數名後面加上一個冒號和空格,然後加上類型名稱。
  這個例子給welcomeMessage 變數添加了類型標註,表示這個變數可以儲存String 類型的值:

var welcomeMessage: String

  聲明中的冒號代表著“是…類型”,所以這行代碼可以被理解為:
  “聲明一個類型為String ,名字為welcomeMessage 的變數。”
  “類型為String ”的意思是“可以儲存任意String 類型的值。”
  welcomeMessage變數現在可以被設定成任一字元串:

welcomeMessage = "Hello"

  注意:
  一般來說你很少需要寫類型標註。如果你在聲明常量或者變數的時候賦了一個初始值,Swift可以推斷出這個常量或者變數的類型,請參考型別安全和類型推斷。在上面的例子中,沒有給welcomeMessage 賦初始值,所以變數welcomeMessage 的類型是通過一個類型標註指定的,而不是通過初始值推斷的。
  常量和變數的命名

let π = 3.14159let 你好 = "你好世界"let = "dogcow"變數名的其他地方包含數字。

一旦你將常量或者變數聲明為確定的類型,你就不能使用相同的名字再次進行聲明,或者改變其儲存的值的類型。同時,你也不能將常量與變數進行互轉。
注意:
如果你需要使用與Swift保留關鍵字相同的名稱作為常量或者變數名,你可以使用反引號(`)將關鍵字包圍的方式將其作為名字使用。無論如何,你應當避免使用關鍵字作為常量或變數名,除非你別無選擇。

你可以更改現有的變數值為其他同類型的值,在下面的例子中, friendlyWelcome 的值從”Hello!” 改為了”Bonjour!” :

var friendlyWelcome = "Hello!"friendlyWelcome = "Bonjour!"// friendlyWelcome 現在是 "Bonjour!"

與變數不同,常量的值一旦被確定就不能更改了。嘗試這樣做會導致編譯時間報錯:

let languageName = "Swift"languageName = "Swift++"// 這會報編譯時間錯誤 - languageName 不可改變
輸出常量和變數

你可以用println

println(friendlyWelcome)// 輸出 "Bonjour!"

println是一個用來輸出的全域函數,輸出的內容會在最後換行。如果你用 Xcode,println 將會輸出內容到“console”面板上。(另一種函數叫print ,唯一區別是在輸出內容最後不會換行。)

println函數輸出傳入的String 值:

println("This is a string")// 輸出 "This is a string"

NSLog函數類似的是,println 函數可以輸出更複雜的資訊。這些資訊可以包含當前常量和變數的值。

Swift 用字串插值(string interpolation)的方式把常量名或者變數名當做預留位置加入到長字串中,Swift 會用當前常量或變數的值替換這些預留位置。將常量或變數名放入圓括弧中,並在開括弧前使用反斜線將其轉義:

println("The current value of friendlyWelcome is \(friendlyWelcome)")// 輸出 "The current value of friendlyWelcome is Bonjour!

注意:
字串插值所有可用的選項,請參考字串插值。

注釋

Swift 中的注釋與C 語言的注釋非常相似。單行注釋以雙正斜杠(//

// 這是一個注釋

你也可以進行多行注釋,其起始標記為單個正斜杠後跟隨一個星號(/* ),終止標記為一個星號後跟隨單個正斜杠(*/ ):

/* 這是一個,多行注釋 */

嵌套成第二個多行注釋。終止注釋時先插入第二個註解區塊的終止標記,然後再插入第一個註解區塊的終止標記:

/* 這是第一個多行注釋的開頭/* 這是第二個被嵌套的多行注釋 *//* 這是第一個多行注釋的結尾 */

通過運用嵌套多行注釋,你可以快速方便的注釋掉一大段代碼,即使這段代碼之中已經含有了多行註解區塊。

分號

與其他大部分程式設計語言不同,Swift 並不強制要求你在每條語句的結尾處使用分號(; ),當然,你也可以按照你自己的習慣添加分號。有一種情況下必須要用分號,即你打算在同一行內寫多條獨立的語句:

let cat = ""; println(cat)// 輸出 ""
整數

整數就是沒有小數部分的數字,比如42 和-23 。整數可以是有符號 (正、負、零)或者無符號 (正、零)。

Swift 提供了8,16,32和64位的有符號和不帶正負號的整數類型。這些整數類型和 C 語言的命名方式很像,比如8位不帶正負號的整數類型是UInt8,32位有符 ,32位有符號整數類型是Int32 。就像> Swift> 的其他類型一樣,整數類型採用大寫命名法。

整數範圍
你可以訪問不同整數類型的min 和max 屬性來擷取對應類型的最大值和最小值:

let minValue = UInt8.min  // minValue 為 0,是 UInt8 類型的最小值let maxValue = UInt8.max  // maxValue 為 255,是 UInt8 類型的最大值

Int
一般來說,你不需要專門指定整數的長度。Swift 提供了一個特殊的整數類型Int ,長度與當前平台的原生字長相同:

在32位平台上,Int 和Int32 長度相同。
在64位平台上,Int 和Int64 長度相同。
除非你需要特定長度的整數,一般來說使用Int 就夠了。這可以提高代碼一致性和可複用性。即使是在32位平台上,Int 可以儲存的整數範圍也可以達到-2147483648 ~2147483647 ,大多數時候這已經足夠大了。

UInt
Swift 也提供了一個特殊的無符號類型UInt ,長度與當前平台的原生字長相同:

在32位平台上,UInt 和UInt32 長度相同。
在64位平台上,UInt 和UInt64 長度相同。
注意:
盡量不要使用UInt ,除非你真的需要儲存一個和當前平台原生字長相同的不帶正負號的整數。除了這種情況,最好使用Int ,即使你要儲存的值已知是非負的。統一使用Int 可以提高代碼的可複用性,避免不同類型數字之間的轉換,並且匹配數位類型推斷,請參考型別安全和類型推斷。

浮點數

浮點數是有小數部分的數字,比如3.14159 ,0.1 和-273.15 。

浮點類型比整數類型表示的範圍更大,可以儲存比Int 類型更大或者更小的數字。Swift 提供了兩種有符號浮點數類型:

Double表示64位浮點數。當你需要儲存很大或者很高精度的浮點數時請使用此類型。
Float表示32位浮點數。精度要求不高的話可以使用此類型。
注意:
Double精確度很高,至少有15位元字,而Float 最少只有6位元字。選擇哪個類型取決於你的代碼需要處理的值的範圍。

型別安全和類型推斷

Swift>是一個型別安全(type safe)的語言。型別安全的語言可以讓你清楚地知道代碼要處理的值的類型。如果你的代碼需要一個String ,你絕對不可能不小心傳進去一個Int 。

由於 >Swift> 是型別安全的,所以它會在編譯你的代碼時進行類型檢查(type checks),並把不匹配的類型標記為錯誤。這可以讓你在開發的時候儘早發現並修複錯誤。

當你要處理不同類型的值時,類型檢查可以幫你避免錯誤。然而,這並不是說你每次聲明常量和變數的時候都需要顯式指定類型。如果你沒有顯式指定類型,Swift 會使用類型推斷(type inference)來選擇合適的類型。有了類型推斷,編譯器可以在編譯代碼的時候自動推斷出運算式的類型。原理很簡單,只要檢查你賦的值即可。

因為有類型推斷,和>C> 或者> Objective-C> 比起來 >Swift> 很少需要宣告類型。常量和變數雖然需要明確類型,但是大部分工作並不需要你自己來完成。

當你聲明常量或者變數並賦初值的時候類型推斷非常有用。當你在聲明常量或者變數的時候賦給它們一個字面量(literal value 或 literal)即可觸發類型推斷。(字面量就是會直接出現在你代碼中的值,比如42 和3.14159 。)

例如,如果你給一個新常量賦值42 並且沒有標明類型,Swift> 可以推斷出常量類型是Int ,因為你給它賦的初始值看起來像一個整數:

let meaningOfLife = 42// meaningOfLife 會被推測為 Int 類型

同理,如果你沒有給浮點字面量標明類型,Swift> 會推斷你想要的是Double :

let pi = 3.14159// pi 會被推測為 Double 類型

當推斷浮點數的類型時,Swift> 總是會選擇Double 而不是Float 。

如果運算式中同時出現了整數和浮點數,會被推斷為Double 類型:

let anotherPi = 3 + 0.14159// anotherPi 會被推測為 Double 類型

原始值3 沒有顯式宣告類型,而運算式中出現了一個浮點字面量,所以運算式會被推斷為Double 類型。

數值型字面量

整數字面量可以被寫作:

一個十進位數,沒有首碼
一個位元,首碼是0b
一個八位元,首碼是0o
一個十六進位數,首碼是0x
下面的所有整數字面量的十進位值都是17 :

let decimalInteger = 17let binaryInteger = 0b10001       // 二進位的17let octalInteger = 0o21           // 八進位的17let hexadecimalInteger = 0x11     // 十六進位的17

浮點字面量可以是十進位(沒有首碼)或者是十六進位(首碼是0x )。小數點兩邊必須有至少一個十進位數字(或者是十六進位的數字)。浮點字面量還有一個可選的指數(exponent),在十進位浮點數中通過大寫或者小寫e 來指定,在十六進位浮點數中通過大寫或者小寫p 來指定。

如果一個十進位數的指數為exp ,那這個數相當於基數和10^exp的乘積:

1.25e2 表示 1.25 × 10^2,等於 125.0 。
1.25e-2表示 1.25 × 10^-2,等於0.0125 。
如果一個十六進位數的指數為exp ,那這個數相當於基數和2^exp的乘積:

0xFp2表示 15 × 2^2,等於60.0 。
0xFp-2表示 15 × 2^-2,等於3.75 。
下面的這些浮點字面量都等於十進位的12.1875 :

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

數值類字面量可以包括額外的格式來增強可讀性。整數和浮點數都可以添加額外的零並且包含底線,並不會影響字面量:

let paddedDouble = 000123.456let oneMillion = 1_000_000let justOverOneMillion = 1_000_000.000_000_1
數值型類型轉換

通常來講,即使代碼中的整數常量和變數已知非負,也請使用Int 類型。總是使用預設的整數類型可以保證你的整數常量和變數可以直接被複用並且可以匹配整數類字面量的類型推斷。 只有在必要的時候才使用其他整數類型,比如要處理外部的長度明確的資料或者為了最佳化效能、記憶體佔用等等。使用顯式指定長度的類型可以及時發現值溢出並且可以暗示正在處理特殊資料。

整數轉換
不同整數類型的變數和常量可以儲存不同範圍的數字。Int8 類型的常量或者變數可以儲存的數字範圍是-128 ~127 ,而UInt8 類型的常量或者變數能儲存的數字範圍是0 ~255 。如果數字超出了常量或者變數可儲存的範圍,編譯的時候會報錯:

let cannotBeNegative: UInt8 = -1// UInt8 類型不能儲存負數,所以會報錯let tooBig: Int8 = Int8.max + 1// Int8 類型不能儲存超過最大值的數,所以會報錯

由於每種整數類型都可以儲存不同範圍的值,所以你必鬚根據不同情況選擇性使用數值型類型轉換。這種選擇性使用的方式,可以預防隱式轉換的錯誤並讓你的代碼中的類型轉換意圖變得清晰。

要將一種數字類型轉換成另一種,你要用當前值來初始化一個期望類型的新數字,這個數位類型就是你的目標類型。在下面的例子中,常量twoThousand 是UInt16 類型,然而常量one 是UInt8 類型。它們不能直接相加,因為它們類型不同。所以要調用UInt16(one) 來建立一個新的UInt16 數字並用one 的值來初始化,然後使用這個新數字來計算:

let twoThousand: UInt16 = 2_000let one: UInt8 = 1let twoThousandAndOne = twoThousand + UInt16(one)

現在兩個數位類型都是UInt16 ,可以進行相加。目標常量twoThousandAndOne 的類型被推斷為UInt16 ,因為它是兩個UInt16 值的和。

SomeType(ofInitialValue)是調用 Swift 構造器並傳入一個初始值的預設方法。在語言內部,UInt16 有一個構造器,可以接受一個UInt8 類型的值,所以這個構造器可以用現有的UInt8 來建立一個新的UInt16 。注意,你並不能傳入任意類型的值,只能傳入UInt16 內部有對應構造器的值。不過你可以擴充現有的類型來讓它可以接收其他類型的值(包括自訂類型),請參考擴充。

整數和浮點數轉換
整數和浮點數的轉換必須顯式指定類型:

let three = 3let pointOneFourOneFiveNine = 0.14159let pi = Double(three) + pointOneFourOneFiveNine// pi 等於 3.14159,所以被推測為 Double 類型

這個例子中,常量three 的值被用來建立一個Double 類型的值,所以加號兩邊的數類型須相同。如果不進行轉換,兩者無法相加。

浮點數到整數的反向轉換同樣行,整數類型可以用Double 或者Float 類型來初始化:

let integerPi = Int(pi)// integerPi 等於 3,所以被推測為 Int 類型

當用這種方式來初始化一個新的整數值時,浮點值會被截斷。也就是說4.75 會變成4 ,-3.9 會變成-3 。

注意:
結合數字類常量和變數不同於結合數字類字面量。字面量3 可以直接和字面量0.14159 相加,因為數字字面量本身沒有明確的類型。它們的類型只在編譯器需要求值的時候被推測。

類型別名

類型別名(type aliases)就是給現有類型定義另一個名字。你可以使用typealias 關鍵字來定義類型別名。

當你想要給現有類型起一個更有意義的名字時,類型別名非常有用。假設你正在處理特定長度的外部資源的資料:

typealias AudioSample = UInt16

定義了一個類型別名之後,你可以在任何使用原始名的地方使用別名:

var maxAmplitudeFound = AudioSample.min// maxAmplitudeFound 現在是 0

本例中,AudioSample被定義為UInt16的一個別名。因為它是別名,AudioSample.min實際上是UInt16.min,所以會給maxAmplitudeFound賦一個初值0。

布爾值

Swift 有一個基本的布爾(Boolean)類型,叫做Bool 。布爾值指邏輯上的(logical),因為它們只能是真或者假。Swift 有兩個布爾常量,true 和false :

let orangesAreOrange = truelet turnipsAreDelicious = false

orangesAreOrange和turnipsAreDelicious 的類型會被推斷為Bool ,因為它們的初值是布爾字面量。就像之前提到的Int 和Double 一樣,如果你建立變數的時候給它們賦值true 或者false ,那你不需要將常量或者變數聲明為Bool 類型。初始化常量或者變數的時候如果所賦的實值型別已知,就可以觸發類型推斷,這讓 Swift 代碼更加簡潔並且可讀性更高。

當你編寫條件陳述式比如if 語句的時候,布爾值非常有用:

if turnipsAreDelicious {    println("Mmm, tasty turnips!")} else {    println("Eww, turnips are horrible.")}// 輸出 "Eww, turnips are horrible."

條件陳述式,例如if ,請參考控制流程。

如果你在需要使用Bool 類型的地方使用了非布爾值,Swift 的型別安全機制會報錯。下面的例子會報告一個編譯時間錯誤:

let i = 1if i {    // 這個例子不會通過編譯,會報錯}

然而,下面的例子是合法的:

let i = 1if i == 1 {    // 這個例子會編譯成功}

i == 1的比較結果是Bool 類型,所以第二個例子可以通過類型檢查。類似i == 1 這樣的比較,請參考基本操作符。

和 Swift 中的其他型別安全的例子一樣,這個方法可以避免錯誤並保證這塊代碼的意圖總是清晰的。

元組

元組(tuples)把多個值組合成一個複合值。元組內的值可以使任意類型,並不要求是相同類型。

下面這個例子中,(404, “Not Found”) 是一個描述 HTTP 狀態代碼(HTTP status code)的元組。HTTP 狀態代碼是當你請求網頁的時候 網頁伺服器返回的一個特殊值。如果你請求的網頁不存在就會返回一個404 Not Found 狀態代碼。

let http404Error = (404, "Not Found")// http404Error 的類型是 (Int, String),值是 (404, "Not Found")

(404, “Not Found”)元組把一個Int 值和一個String 值組合起來表示 HTTP 狀態代碼的兩個部分:一個數字和一個人類可讀的描述。這個元組可以被描述為“一個類型為(Int, String) 的元組”。

你可以把任意順序的類型組合成一個元組,這個元組可以包含所有類型。只要你想,你可以建立一個類型為(Int, Int, Int) 或者(String, Bool) 或者其他任何你想要的組合的元組。

你可以將一個元組的內容分解(decompose)成單獨的常量和變數,然後你就可以正常使用它們了:

let (statusCode, statusMessage) = http404Errorprintln("The status code is \(statusCode)")// 輸出 "The status code is 404"println("The status message is \(statusMessage)")// 輸出 "The status message is Not Found"

如果你只需要一部分元組值,分解的時候可以把要忽略的部分用底線(_)標記:

let (justTheStatusCode, _) = http404Errorprintln("The status code is \(justTheStatusCode)")// 輸出 "The status code is 404"

此外,你還可以通過下標來訪問元組中的單個元素,下標從零開始:

println("The status code is \(http404Error.0)")// 輸出 "The status code is 404"println("The status message is \(http404Error.1)")// 輸出 "The status message is Not Found"

你可以在定義元組的時候給單個元素命名:

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

給元組中的元素命名後,你可以通過名字來擷取這些元素的值:

println("The status code is \(http200Status.statusCode)")// 輸出 "The status code is 200"println("The status message is \(http200Status.description)")// 輸出 "The status message is OK"

作為函數傳回值時,元組非常有用。一個用來擷取網頁的函數可能會返回一個(Int, String) 元組來描述是否擷取成功。和只能返回一個類型的值比較起來,一個包含兩個不同類型值的元組可以讓函數的返回資訊更有用。請參考函數參數與傳回值。

注意:
元組在臨時組織值的時候很有用,但是並不適合建立複雜的資料結構。如果你的資料結構並不是臨時使用,請使用類或者結構體而不是元組。請參考類和結構體。

可選類型
使用可選類型(optionals)來處理值可能缺失的情況。可選類型表示:

有值,等於 x
或者

沒有值
注意:
C 和 Objective-C 中並沒有可選類型這個概念。最接近的是 Objective-C 中的一個特性,一個方法要不返回一個對象要不返回nil ,nil 表示“缺少一個合法的對象”。然而,這隻對對象起作用——對於結構體,基本的 C 類型或者枚舉類型不起作用。對於這些類型,Objective-C 方法一般會返回一個特殊值(比如NSNotFound )來暗示值缺失。這種方法假設方法的調用者知道並記得對特殊值進行判斷。然而,Swift 的可選類型可以讓你暗示任意類型的值缺失,並不需要一個特殊值。
來看一個例子。Swift 的String 類型有一個叫做toInt 的方法,作用是將一個String 值轉換成一個Int 值。然而,並不是所有的字串都可以轉換成一個整數。字串”123” 可以被轉換成數字123 ,但是字串”hello, world” 不行。

下面的例子使用toInt 方法來嘗試將一個String 轉換成Int :

let possibleNumber = "123"let convertedNumber = possibleNumber.toInt()// convertedNumber 被推測為類型 "Int?", 或者類型 "optional Int"

因為toInt 方法可能會失敗,所以它返回一個可選類型(optional)Int ,而不是一個Int 。一個可選的Int 被寫作Int? 而不是Int 。問號暗示包含的值是可選類型,也就是說可能包含Int 值也可能不包含值。(不能包含其他任何值比如Bool 值或者String 值。只能是Int 或者什麼都沒有。)

if 語句以及強制解析
你可以使用if 語句來判斷一個可選是否包含值。如果可選類型有值,結果是true ;如果沒有值,結果是false 。

當你確定可選類型確實包含值之後,你可以在可選的名字後面加一個驚嘆號! 來擷取值。這個驚歎號表示“我知道這個可選有值,請使用它。”這被稱為可選值的強制解析(forced unwrapping):

if convertedNumber {    println("\(possibleNumber) has an integer value of \(convertedNumber!)")} else {    println("\(possibleNumber) could not be converted to an integer")}// 輸出 "123 has an integer value of 123"

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.