iOS開發之Swift篇(2)—— 基礎部分

版本

Xcode 11.0
Swift 5.1

基本語法

1. Swift 引入

我們可以使用 import 語句來引入任何的 Objective-C 框架(或 C 庫)到 Swift 程序中。例如 import cocoa 語句導入了使用了 Cocoa 庫和API,我們可以在 Swift 程序中使用他們。
使用本工程swift文件無需import, 可直接使用。

2. 註釋

// 單行註釋
/* 多行註釋1
多行註釋2 */
/* 嵌套註釋1
/* 嵌套註釋內容 */
嵌套註釋2 */

3. 分號

OC代碼行尾需加分號";"(甚至加兩個分號都不報錯), 而Swift不需要加分號, 如喜歡也可加一個分號(加兩個分號會報錯). 如果兩句代碼寫在同一行, 則需要分號隔開.

print("111"); print("222")

4. Swift 空格

Swift語言並不是像C/C++,Java那樣完全忽視空格,Swift對空格的使用有一定的要求,但是又不像Python對縮進的要求那麼嚴格。在Swift中,運算符不能直接跟在變量或常量的後面。
錯誤:

let a= 1 + 2    // 報錯  error: prefix/postfix '=' is reserved
let a = 1+ 2    // 報錯  因爲Swift認爲到1+這個語句就結束了,2就是下一個語句了

正解:

let a = 1 + 2   // 編碼規範推薦使用這種寫法
let b = 3+4     // 這樣也是OK的

5. 打印輸出

Swift 使用 print 函數打印輸出:

print("Hello, world!")    // 輸出字符串 Hello, world!

print 函數是一個全局函數,完整的函數聲明爲:

public func print(items: Any..., separator: String = default, terminator: String = default)

如果我們想讓其不換行輸出,只需要將最後一個參數賦值爲空字符串即可:

for x in 0...10{
    print("\(x) ", terminator: "")
}
print()    // 加這句是爲了在for打印結束後換行

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

let aa = "abc"
print("字符串 aa = \(aa)")
// 打印輸出 字符串 aa = abc

數據類型

Swift 包含了 C 和 Objective-C 上所有基礎數據類型,Int 表示整型值; Double 和 Float 表示浮點型值; Bool 是布爾型值;String 是文本型數據。 Swift 還提供了三個基本的集合類型,Array、Set 和 Dictionary。
除了我們熟悉的類型,Swift 還增加了 Objective-C 中沒有的高階數據類型比如元組(Tuple)。元組可以讓你創建或者傳遞一組數據,比如作爲函數的返回值時,你可以用一個元組可以返回多個值。
Swift 還增加了可選(Optional)類型,用於處理值缺失的情況。可選表示 “那兒有一個值,並且它等於 x ” 或者 “那兒沒有值” 。可選有點像在 Objective-C 中使用 nil ,但是它可以用在任何類型上,不僅僅是類。可選類型比 Objective-C 中的 nil 指針更加安全也更具表現力,它是 Swift 許多強大特性的重要組成部分。
綜上, Swift中數據類型包含但不限於以下:

  • Int
  • Double/Float
  • Bool
  • String
  • Array
  • Set
  • Dictionary
  • Tuple

常量和變量

常量和變量把一個名詞(比如 age)和一個指定類型的值(比如數字 18)關聯起來。常量的值一旦設定就不能改變,而變量的值可以隨意更改。

1. 聲明

常量和變量必須在使用前聲明,用 let(讓) 來聲明常量,用 var(variable) 來聲明變量。

let a = 0
var b = 1
let c = 2, d = 33.3

2. 類型註解

當你聲明常量或者變量的時候可以加上類型註解(type annotation),說明常量或者變量中要存儲的值的類型。如果不寫註解也是可以的, Swift 可以推斷出這個常量或者變量的類型, 詳見後文類型推斷.

var aa:String = "aa"
var bb, cc: String    // 兩個一起註解不能直接賦值
bb = "bb"
cc = "cc"
print(aa, bb, cc)

類型安全/推斷/轉換

1. 類型安全

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

var name = "XiaoMing"
name = 18    // 報錯 Cannot assign value of type 'Int' to type 'String'

2. 類型推斷

由於 Swift 是類型安全的,所以它會在編譯你的代碼時進行類型檢查(type checks),並把不匹配的類型標記爲錯誤。
如果你沒有顯式指定類型 (上文提到的類型註解),Swift 會使用類型推斷(type inference)來選擇合適的類型。有了類型推斷,編譯器可以在編譯代碼的時候自動推斷出表達式的類型。原理很簡單,只要檢查你賦的值即可。

let age = 18
// age 會被推測爲 Int 類型

let pi = 3.14159
// pi 會被推測爲 Double 類型 (當推斷浮點數的類型時,Swift 總是會選擇 Double 而不是 Float。)

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

3. 類型轉換

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

let aa: UInt16 = 800
let bb: UInt8 = 1
let cc = aa + UInt16(bb)

注: omeType(ofInitialValue) 是調用 Swift 構造器並傳入一個初始值的默認方法。在語言內部,UInt16 有一個構造器,可以接受一個 UInt8 類型的值,所以這個構造器可以用現有的 UInt8 來創建一個新的 UInt16。注意,你並不能傳入任意類型的值,只能傳入 UInt16 內部有對應構造器的值。不過你可以擴展現有的類型來讓它可以接收其他類型的值(包括自定義類型)。

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

let three = 3
let dec = 0.14159
let pi = Double(three) + dec

ps: 所謂顯式, 指代碼標明且能體現出來, 比如上文的Double(three)轉換;
隱式, 比如C中 float aa = 1; 1是int類型, 但賦予aa的時候被隱式轉換成了float.

可選類型

可選類型(optionals)用來表示有值或者沒有值兩種情況. 有值, 纔可以解析可選類型訪問這個值.

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

先來看個例子:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
print(possibleNumber)
print(convertedNumber)    // 警告

// 打印結果
// 123
// Optional(123)

convertedNumber 被推測爲類型 “Int?”, 或者類型 “optional Int”. 因爲Int()並不能總是返回一個int類型, 傳入"123"能返回值123, 而傳入"Hello, world"則沒有返回值.

1. 寫法

var possibleNumber: Int? = 123

2. nil

如果你聲明一個可選常量或者變量但是沒有賦值,它們會自動被設置爲 nil:

var aa: String?
// aa 被自動設置爲 nil

可以手動設置爲nil:

var aa: Int? = 11    // aa 包含一個可選的 Int 值 11
aa = nil             // 手動設置爲nil

注意:
Swift 的 nil 和 Objective-C 中的 nil 並不一樣。在 Objective-C 中,nil 是一個指向不存在對象的指針。在 Swift 中,nil 不是指針——它是一個確定的值,用來表示值缺失。任何類型的可選狀態都可以被設置爲 nil,不只是對象類型。

3. 強制解析

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

let aa:String? = "123"
print(aa!)
print("字符串 aa = \(aa!)")

注意:
使用 ! 來獲取一個不存在的可選值會導致運行時錯誤。使用 ! 來強制解析值之前,一定要確定可選包含一個非 nil 的值。

4. 隱式解析

有時候在程序架構中,第一次被賦值之後,可以確定一個可選類型總會有值。在這種情況下,每次都要判斷和解析可選值是非常低效的,因爲可以確定它總會有值。
這種類型的可選狀態被定義爲隱式解析可選類型(implicitly unwrapped optionals)。把想要用作可選的類型的後面的問號(String?)改成感嘆號(String!)來聲明一個隱式解析可選類型。
例如:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString!  // 需要感嘆號來獲取值

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString  // 不需要感嘆號

print(assumedString!)    // 仍然需要感嘆號, 知道的朋友望不吝賜教.

5. 可選綁定

使用可選綁定(optional binding)來判斷可選類型是否包含值,如果包含就把值賦給一個臨時常量或者變量。可選綁定可以用在 if 和 while 語句中,這條語句不僅可以用來判斷可選類型中是否有值,同時可以將可選類型中的值賦給一個常量或者變量。
例如:

let aa:String? = "abc"
if let bb = aa {
    print("aa有值 \(bb)")
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章