Swift 個人學習筆記 – 01: A Swift Tour

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

本文章純粹是中文版《The Swift Programming Language》的學習筆記,所以絕大部分的內容都是文中有的。本文是本人的學習筆記,不是正式系統的記錄。僅供參考

以下還是有很多沒看懂、不確定的地方,我會以“存疑”的註解指出。

在此感謝中文版翻譯者,這極大地加快了 Swift 的學習速度。


Reference:

原版:The Swift Programming Language
中文版:Swift 3 程式語言

幾個無法分類的知識:
1 – Swift 不需要 main()函式,全域性的第一段程式碼就是程式的入口。(存疑)
2 – Swift 中沒有像 C 裡面一樣,非常明確地區別“宣告”和“定義”的概念,全部的定義都是 “宣告 定義”。

變數和常量

宣告變數和常量

let aConstant = 42
let aConstantDouble : Double = 70   // 個人推薦

這樣根據後面的值假定常量的型別。第一個例子裡面,常量的型別就被設定成了Int。而第二個例子裡面,雖然初始化值給的是一個Int,但是前面顯式地說明了這是一個Double型別變數,所以這就是一個 Double 型別。

變數使用的是var

陣列

在 Swift 裡面,陣列和關聯陣列成為了基本資料型別(在 Objective-C 裡面是類),這大大簡化了資料操作。
宣告方式如下:

var shoppingList = ["catfish", "water", "popcorn"]
var shoppingList = [String]()

其中第一行是定義 初始值。第二行則不賦予初始值

關聯陣列(Dictionary)

var aDict = [:]
var aDict = [String:Float]()        // 推薦
var aListOfSalaries = [
"Andrew": 10000.0,
"Bob": 15000.0
]

上面第二種方法是詳細的定義,具體限制了關聯陣列的 key 和 value 的型別。

控制流

基本上和 C 差不多,但不需要括號。不過有{}
條件操作有:ifswitch
迴圈操作有:for-inforwhilerepeat-while(不是 “do-while”)。

注意if的條件不循序用一個普通變數的值作為判斷條件體了,只能布林判斷值。比如 “if some_value” 就是不合法的寫法。

Optional 變數

如果宣告變數的時候加入?,那麼變數就是可選的(optional)
此時,變數可以置為 nil 值。

猜測這個方法就是相當於 C 裡面的指標或者是其他方法中的引用(不確定)。

Arrar 和 Dictionary 中的 for-in

for number in someArray {
...
}
for (kind, number) in someDictionary {
...
}

上面是使用 “for-in” 語法來 access array 和 dict 的方法。當然,array 和 dict 也可以巢狀。

迴圈

while n < 200 { ... }
repeat { ... } while m < 100
for i in 0..<4 {   }         // 表示 [0,4)
for i in 0...4 {   }         // 表示 [0,4]

函式和簇(閉包)

使用 func 來宣告和定義函式:

func greeting (persion: String, day: String) -> String {
...
}

可以使用 “元組”(tuple)來建立僅在該函式中使用的複合值(類似 struct):

func calculate (scores:[Int]) -> (min: Int, max: Int, sum: Int) {
...
}

此外,可以把函式作為值返回:

func theFunc(number: Int) -> Int { ... }
func retuanAFunc() -> (Int -> Int) {
return theFunc
}

函式可以內嵌,內嵌的函式可以訪問外部的變數:

func someFunc() -> Int {
var error: Int = 0
...
func checkError() {
if (...) { error = -1 }
}
...
return error
}

物件和類

使用關鍵字 class 加花括號來構建一個類。與前面其他格式中花括號的作用一眼,都只是用來作為作用域。

var anInstance = aClass    // 很像 C  

使用點語法來訪問類中的成員與方法。

初始化函式:init,接近 Objective-C 中的 init
反初始化函式:deinit,接近 Objective-C 中的 dealloc
成員函式過載:在 func 前面加上 override 關鍵字。

getter / setter

宣告成員時,額外可以宣告 getter / setter:

class SomeClass : FatherClass {
var radius : Int
init (radius : Int) {
super.init (radius)
self.radius = radius
}
var circle : Double {
get {
...
}
set {
...        // setter的引數如果未定義的話,預設叫做 `newValue`。也可以顯式地定義。
}
}
}

willset 和 didSet

有時候,如果不需要自行實現 set / get操作,但需要在值更新前後操作的話,可以針對該值定義 willSetdidSet 函式:

var squre : Double {
willSet: {
...
}
}

列舉和結構體

這其實是我最搞不懂的元素之一了,目測我以後只會用最基礎的部分。
使用 enum 建立列舉。enum 可以包括函式:

enum PokerFace {
case ace = 1            // 注意這裡如果不賦初始值的話,預設是 1
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king
func decription() -> String {
switch self {
case .ace:
return "ace"
case .jack:
return "jack"
case .queen:
return "queen"
case .king:
return "king"
default:
return String (self.rawValue)        // Note
}
}
}

注意隱含的 rawValue 值。

可以用建構函式建立一個 enum 的例項:

let aRank = Rank (rawValue : 3)
let aRank = Rank (.three)

使用 struct 定義結構體:

struct Card_st {
var rank : Rank
var suit : Suit
func simpleDescription () -> String {
return ...
}
}

struct 的行為與 class 很類似,但傳遞時,struct 傳遞的是拷貝,而 class 傳遞的是引用
struct 也有 initializer

協議和擴充套件

協議

protocol ExampleProtocol {
var simpleDescription: String {get}
mutating func adjust ()
}

宣告部分的兩行分別代表一下意思:

  1. 有一個針對 simpleDescritpion 的 String 的 getter
  2. 宣告一個函式:其中 mutating 關鍵字用在 struct 中,表示可以修改 struct 的內容。

class、struct 和 enum 都可以有協議。

宣告一個類,表示符合某個協議,在冒號後面加就好了:

class SomeClass : ExampleProtocol {
...
}

擴充套件

extansion Int: ExampleExtansion {
...
}

上面表示為 Int 型別新增一個名為 “ExampleExtension” 的擴充套件。

此時你可以建立一個叫做 “ExampleProtocol” 的 Int 變數,這個時候, “ExampleExtension” 的語義就變成了 “新增了 ExampleExtension 擴充套件的 Int 型別”。這是的基本型別也好像類一樣繼承了。

錯誤處理

使用遵循 Error 協議的型別來表示錯誤,比如:

enum ExampleError : Error {
case outOfPaper
case noToner
case onFire
}

使用 throw 來丟擲錯誤。使用 throws 標記可以丟擲錯誤的函式:

func send (job : Int, toPrinter printerName : String) throws -> String {
...
if printerName == ... {
throw ExampleError.noToner
}
return "..."
}

錯誤處理方法1:do-catch

do {
...
} catch {
print(error)        // 這個貌似是隱含的資料型別?不確定
}

錯誤處理方法2:do 多個catch

do {
...
} catch PrinterError.onFire {
...
} catch let printerError as PrinterError {
print ("Printer error: \(printerError).")
} catch {
print(error)
}

錯誤處理方法3:try?
沒明白

下一篇

Swift 個人學習筆記 – 02: 基礎內容

相關文章

IOS開發 最新文章