零基礎學iOS系列之swift語法基礎

2020-08-11 17:41:52

1. 變數與數據型別

a) 數據型別

i. 基本數據型別

整數型別 Int, UInt, Int8, UInt8, Int16,UInt16, Int32, UInt32, Int64, UInt64

實數型別 Double, CGFloat

字串 String

集合型別 Array, Dictionary, Set

ii. 型別之間的轉換(呼叫目標型別的建構函式)

整數型別 –> 實數型別:

let n: Int = 0 
let b = Double(n)

數位型別 -> 字串型別:

let number = 4
let string = String(number)

b) 變數的宣告

i. 基本宣告方法

let/var name[: Type][ = Initialization],中括號內表示可省略, 但第一個中括號與第二個中括號內的內容只能省略一處, 除了類成員屬性有預設值的情況不需要省略,其他均建議採用省略形式, 如

let number = 1

var string: String?

ii. 使用let宣告

表示常數,宣告之後只允許有一次賦值, 如

let x = 10

x = 100 //編譯不通過

iii. 使用var宣告

表示變數, 一次宣告,可以多次修改其值, 但效率沒有let高

var name = "小明"

///...

name = "大明"

iv. let 與var的區別與使用規則

區別在於前者宣告的變數爲值不可變,後者值可變,前者效率更高,使用原則:

方法體中,優先使用let, 當需要修改變數值的時候, 根據編譯器提示和修改建議進行修改即可

v. 語法糖

適用於ArrayDictionaryOptional, 但寫法更簡潔,

對於陣列, 應該寫成

let array: [Int]

而不建議寫成

let array: Array<Int>

對於字典, 應該寫成

let dict: [String:String]

而不應該寫成

let dict: Dictionary<String,String>

對於Optional,從名字上看叫可選值, 也就是可空值, 表示該型別的變數的值可以是nil(或者.None), 建議使用簡潔形式宣告可選型別變數, 如

var name: String?

而不要使用

var name: Optional<String>

c) 區間

區間分爲半開區間和閉區間,區間值必須爲整數, 半開區間用..<表示, 如0到99, 則可以表示

0..<100

閉區間用表示, 如0到99表示爲

099

2. 控制語句

a) 條件語句

i. if else語句

最基本的條件判斷,

if 條件 {
    條件爲真的時候的操作
} else {
    條件爲假時的操作
}

else 後仍可接ifelse完成語句,如:


if 條件1 {
   /// 條件1爲真的時候的操作
} else if 條件2 {
   /// 條件2爲真的時候的操作
} else{
   ///條件爲假時的操作
}

ii. guard else 語句

guard 條件 else{
    return/break
}

表示確保條件成立的情況下繼續往下執行,否則執行完else中的內容後退出,break/return要求必須寫一個,因此guard語句一般在方法體中或者回圈中使用,具體看使用情況,guard else語句一般用來避免巢狀if else語句造成的程式碼結構混亂

iii. if let 語句

表示可選值的系結,如果可選值非空,可以系結成功,則執行後面{ }中的語句,否則跳過{ }

形式:


if let some = someOptioal {

    如果someOptional的值不是nil,則執行此處程式碼

}

if let語句也可以和if else語句一樣,可以有else分支,如果有多個可選值需要系結,只需要在{ }前面增加let 語句即可,然後與前面的語句用英文逗號隔開

if let 語句可以用來避免使用!進行強制拆包導致的nil異常

iv. guard let … else語句

類似於if let,同樣用於可選值系結,系結失敗則執行else 後面的{ }裏面的語句並退出

b) 選擇語句

switch case語句

使用形式:

switch some {

case value1:

    ...

case value2:

    ...

default: break

}

使用要求, 如果some爲列舉型別的變數,則不建議使用default分支, 應該將所有列舉值case 出來, 如果some爲非列舉型別變數,則要求必須有default分支,且每一個case分支下如果語句非空, 則不需要使用break,否則需要在該分支使用break,case 分支的值除了可以是單個的值之外,也可以是區間

c) 回圈語句

i. 傳統for回圈

for init; condition; change{
/// loop body
}

傳統的for回圈, 不建議使用

ii. for in

for some in collection {
/// loop body
} 

用於對集合型別的遍歷, 建議使用

iii. while 語句

while condition {
/// 回圈體
}

iv. repeat語句

repeat {
/// 回圈體
} while condition

與while回圈功能相同, 但是區別在於while回圈先判斷在執行, repeat while語句先執行後判斷

d) 回圈中的跳轉

跳過當前回圈,使用continue, 終止當前回圈,使用break, break可以終止多層回圈,配合標籤使用, 如

lp:
for i in 0..<10 {
    for j in 0..<5 {
       if i* i == j * j * j {
           break lp
       }	
	}
}

3. 自定義型別

a) typealias使用

給已有型別取別名, 如

typealias Point = (Double, Double)

表示將(Double, Double)型別的元組取別名爲Point

b) enum

定義列舉型別, 列舉值以case 爲字首列舉, 如

enum School{

case primary

case middleSchool

case university

case college

}

與其他語言不同, 列舉值中也可以有包括構造方法在內的方法存在,也可以以其他如Int 型別爲父類別進行繼承

c) tuple

元組型別, 用來包裹多個不同數據型別的集合型別。有點類似結構體,但不需要像結構體一樣預先定義

let student = ("Oyoung", 26, "男")
student.0 // "Oyoung"
student.1 // 26
student.2 // "男"
typealias Student = (name: String, age: Int, gender: String)

let namedStudent: Student = student

namedStudent.name  /// <=> namedStudent.0
namedStudent.age  /// <=> namedStudent.1
namedStudent.gender  /// <=> namedStudent.2

d) struct

宣告一個類,但是該類屬於值型別,每一個該型別的變數之間互不相關,修改任何一個該型別變數不會影響到其他同類型變數的值

struct Point {
	var x: Int
	var y: Int
}

let pointA = Point(x: 0, y: 0)
let pointB = pointA

pointB.x = 100
pointB.y = 200

println(pointA.x == pointB.x) /// false
println(pointA.x == pointB.y) /// false


e) class

與struct相同,也是宣告一個類, 但區別在於, 宣告的類爲參照型別,如果將該型別的一個變數賦值給另一個同類型變數,則這兩個變數指向的是同一個實體,如果有其中一個變數修改了實體的某個值, 另一個變數的實體的值會跟着修改

class Student {
	var name: String
	var number: Int
	var age: Int
}

let xiaoming = Student(name: "小明", number: 10001, age: 16)
let theMonitor = xiaoming

theMonitor.age += 1

println (xiaoming.age) /// 17

f) protocol

表示協定, 用來宣告介面, 宣告後不可直接使用,只能使用class或者struct宣告的類實現該協定

protocol Writable {
	func write(data: Data) -> Int
}

class Buffer {
	private var data: [UInt8] = [UInt8]()
}

extension Buffer: Writbale {
	func write(data: Data) -> Int {
		self.data += data.map{$0}
		return data.count
	}
}