Swift語言系統(tǒng)總結(jié)

Swift學(xué)習(xí)總結(jié)老師

語言基礎(chǔ)

程序是指令的集合歹嘹,寫程序就是寫一系列的指令去控制計算機(jī)做我們想做的事情。
編譯:將程序設(shè)計語言轉(zhuǎn)換成計算機(jī)能夠理解的機(jī)器語言或者某種中間代碼的過程徒溪。

馮諾依曼體系結(jié)構(gòu)的計算機(jī):

  1. 使用二進(jìn)制
  2. 程序存儲執(zhí)行

變量和常量

定義變量和常量是為了保存數(shù)據(jù),變量和常量就是某種類型的值的存儲空間金顿。

var a: Int = 10
a = 100
var b: Int
b = 1000
var c = 10000

let d: Int = 10
// d = 100      // compiler error
let e = 1000

說明:1. Swift有非常強(qiáng)大的類型推斷臊泌,所以定義變量或常量時如果可以的話應(yīng)該直接使用類型推斷不用手動指定類型;2. 如果可以的話應(yīng)該盡可能使用常量而不是變量揍拆。

語言元素

var a: Int = 10

關(guān)鍵字:有特殊含義的單詞
標(biāo)識符:給變量渠概、常量、函數(shù)嫂拴、類播揪、結(jié)構(gòu)、協(xié)議筒狠、枚舉猪狈、方法、屬性等起的名字

  1. 字母(Unicode字符)辩恼、數(shù)字罪裹、下劃線,數(shù)字不能開頭
  2. 大小寫敏感(區(qū)分大小寫)
  3. 不能使用關(guān)鍵字做標(biāo)識符
  4. 使用駝峰命名法(命名變量运挫、常量状共、函數(shù)、方法谁帕、屬性第一個單詞小寫峡继,從第二個單詞開始每個單詞首字母大寫;命名類匈挖、結(jié)構(gòu)碾牌、協(xié)議、枚舉每個單詞首字母都要大寫)
  5. 見名知意
  6. 命名私有的屬性和方法時以下劃線開頭

運(yùn)算符:Swift中的運(yùn)算符其實(shí)都是函數(shù)

  1. 賦值運(yùn)算符:=儡循、+=舶吗、-=、……
  2. 算術(shù)運(yùn)算符:+择膝、-誓琼、*、/、%
  3. 比較運(yùn)算符:==腹侣、!=叔收、<、<=傲隶、>饺律、>=
  4. 邏輯運(yùn)算符:&&、||跺株、!
  5. 條件運(yùn)算符:?:
  6. 其他運(yùn)算符:[]复濒、.、??乒省、?巧颈、!

字面(常)量:

  1. 整數(shù)字面量:10、1_234_567作儿、0x10洛二、0o10、0b10
  2. 小數(shù)字面量:123.45攻锰、1.2345e2晾嘶、0xab.cdp2
  3. 字符字面量:"c"、"\n"娶吞、"\u{41}"垒迂、"\u{9a86}"
  4. 字符串字面量:"Hello"、"caf\u{e9}"
  5. 布爾字面量:true妒蛇、false
  6. 空值字面量:nil
  7. 類型字面量:String.self机断、UILabel.self

分隔符:將不同的語言元素符號分開

說明:Swift中每個語句后面的分號是可寫可不寫的,寫代碼時盡量保證一行只有一條語句這樣就可以省略掉分號绣夺。

分支和循環(huán)

分支

  • if...else...

下面的程序?qū)崿F(xiàn)了分段函數(shù)求值吏奸。

let x = 3.2
let y: Double
if x < -1 {
    y = 3 * x + 5
}
else if x <= 1 {
    y = 5 * x - 3
}
else {
    y = 7 * x + 1
}
print("f(\(x))=\(y)")
  • switch...case...default

下面的程序?qū)崿F(xiàn)了將百分制的成績轉(zhuǎn)換成A-E的等級。

let score = 92.5
let level: String
switch score {
case 0..<60:
    level = "E"
case 60..<70:
    level = "D"
case 70..<80:
    level = "C"
case 80..<90:
    level = "B"
case 90...100:
    level = "A"
default:
    level = "輸入錯誤"
}
print(level)

循環(huán)

  • while

下面的程序?qū)崿F(xiàn)了1-100求和陶耍。

var sum = 0
var i = 1
while i <= 100 {
    sum += i
    i += 1
}
print(sum)
  • repeat...while...

下面的程序?qū)崿F(xiàn)了1-100求和奋蔚。

var sum = 0
var i = 1
repeat {
    sum += i
    i += 1
} while i <= 100
print(sum)
  • for

下面的程序?qū)崿F(xiàn)了1-100求和。

var sum = 0
for i in 1...100 {
    sum += i
}
print(sum)

窮舉法:窮盡所有可能性直到找到正確答案烈钞。

下面的程序?qū)崿F(xiàn)了"百錢百雞"問題的求解泊碑。

for x in 0...20 {
    for y in 0...33 {
        let z = 100 - x - y
        if 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0 {
            print("公雞: \(x), 母雞: \(y), 小雞: \(z)")
        }
    }
}

說明:在循環(huán)中可以使用break關(guān)鍵字來提前終止循環(huán),也可以使用continue關(guān)鍵字使循環(huán)直接進(jìn)入下一輪毯欣,但是應(yīng)該盡量減少對break和continue的使用馒过,因?yàn)樗鼈儾粫屇愕某绦蜃兊酶谩?/p>

綜合案例:Craps賭博游戲。

游戲規(guī)則:玩家搖兩顆色子酗钞,如果第一次搖出了7點(diǎn)或11點(diǎn)腹忽,玩家勝来累;如果搖出2點(diǎn)、3點(diǎn)或12點(diǎn)留凭,莊家勝佃扼;其他點(diǎn)數(shù)游戲繼續(xù)偎巢。在繼續(xù)的過程中玩家重新?lián)u色子蔼夜,如果搖出了7點(diǎn),莊家勝压昼;如果搖出了第一次搖的點(diǎn)數(shù)求冷,玩家勝;否則玩家繼續(xù)搖色子直到分出勝負(fù)窍霞。

func roll() -> Int {
    return Int(arc4random_uniform(6)) + 1
}

let firstPoint = roll() + roll()
print("玩家搖出了\(firstPoint)點(diǎn)")
var needsGoOn = false
switch firstPoint {
case 7, 11: print("玩家勝!")
case 2, 3, 12: print("莊家勝!")
default: needsGoOn = true
}
while needsGoOn {
    let currentPoint = roll() + roll()
    print("玩家搖出了\(currentPoint)點(diǎn)")
    if currentPoint == 7 {
        print("莊家勝!")
        needsGoOn = false
    }
    else if currentPoint == firstPoint {
        print("玩家勝!")
        needsGoOn = false
    }
}

容器

數(shù)組

數(shù)組是使用連續(xù)的內(nèi)存空間保存多個同類型的元素的容器匠题,因?yàn)閿?shù)組中的元素在內(nèi)存中是連續(xù)的,所以可以使用下標(biāo)運(yùn)算來訪問數(shù)組中的元素但金,實(shí)現(xiàn)隨機(jī)存取韭山。

  • 創(chuàng)建數(shù)組
var array1: [Int] = []
var array2: Array<Int> = []
var array3 = [1, 2, 3, 4, 5]
var array4 = [Int](count: 5, repeatedValue: 0)
var array5 = Array<Int>(count: 5, repeatedValue: 0)
  • 添加元素
array1.append(2)
array1.append(3)
array1.insert(1, atIndex: 0)
array1.insert(4, atIndex: array1.count)
array1 += [5]
array1 += [6, 7, 8]
  • 刪除元素
array1.removeAtIndex(2)
array1.removeFirst()
array1.removeFirst(2)
array1.removeLast()
array1.removeRange(1...2)
array1.removeAll()
  • 修改元素
array3[0] = 100
array3[array3.count - 1] = 500
  • 遍歷數(shù)組
  1. 方式1
for i in 0..<array3.count {
    print(array3[i])
}
  1. 方式2
for temp in array3 {
    print(temp)
}
for temp in array3[1...3] {
    print(temp)
}

說明:for-in循環(huán)是一個只讀循環(huán),這也就意味著再循環(huán)的過程中不能對數(shù)組中的元素進(jìn)行修改

  1. 方式3
for (i, temp) in array3.enumerate() {
    if i == 0 {
        array3[i] = 1
    }
    print("\(i). \(temp)")
}

提醒:操作數(shù)組時最重要的是不要越界訪問元素冷溃。數(shù)組對象的count屬性表明了數(shù)組中有多少個元素钱磅,那么有效的索引(下標(biāo))范圍是0到count-1。

數(shù)組中的元素也可以是數(shù)組似枕,因此我們可以構(gòu)造多維數(shù)組盖淡。最常見的是二維數(shù)組,它相當(dāng)于是一個有行有列的數(shù)組凿歼,數(shù)組中的每個元素代表一行褪迟,該數(shù)組中的每個元素代表行里面的列。二維數(shù)組可以模擬現(xiàn)實(shí)世界中的表格答憔、數(shù)學(xué)上的矩陣味赃、棋類游戲的棋盤、2D游戲中的地圖虐拓,所以在實(shí)際開發(fā)中使用非常廣泛心俗。

下面的程序是用二維數(shù)組模擬表格的例子。

func randomInt(min: UInt32, max: UInt32) -> Int {
    return Int(arc4random_uniform(max - min + 1) + min)
}

let namesArray = ["關(guān)羽", "張飛", "趙云", "馬超", "黃忠"]
let coursesArray = ["語文", "數(shù)學(xué)", "英語"]

var scoresArray = [[Double]](count: namesArray.count, repeatedValue: [Double](count: coursesArray.count, repeatedValue: 0))

for i in 0..<scoresArray.count {
    for j in 0..<scoresArray[i].count {
        scoresArray[i][j] = Double(randomInt(50, max: 100))
    }
}

for (index, array) in scoresArray.enumerate() {
    var sum = 0.0
    for score in array {
        sum += score
    }
    let avg = sum / Double(coursesArray.count)
    print("\(namesArray[index])的平均成績?yōu)? \(avg)")
}

for i in 0..<coursesArray.count {
    var sum = 0.0
    for row in 0..<scoresArray.count {
        sum += scoresArray[row][i]
    }
    let avg = sum / Double(namesArray.count)
    print("\(coursesArray[i])課的平均成績?yōu)? \(avg)")
}

集合

集合在內(nèi)存中是離散的侯嘀,集合中的元素通過計算Hash Code(哈希碼或散列碼)來決定存放在內(nèi)存中的什么位置另凌,集合中不允許有重復(fù)元素。

  • 創(chuàng)建集合
var set: Set<Int> = [1, 2, 1, 2, 3, 5]
  • 添加和刪除元素
set.insert(100)

set.remove(5)
set.removeFirst()
set.removeAll()
  • 集合運(yùn)算(交集戒幔、并集吠谢、差集)
var set1: Set<Int> = [1, 2, 1, 2, 3, 4, 5]
var set2: Set<Int> = [1, 3, 5, 7]

set1.intersect(set2)
set1.union(set2)
set1.subtract(set2)

字典

字典是以鍵值對的方式保存數(shù)據(jù)的容器,字典中的每個元素都是鍵值對組合诗茎,通過鍵可以找到對應(yīng)的值工坊。

  • 創(chuàng)建字典
var dict = [
    1: "hello",
    2: "good",
    3: "wonderful",
    5: "delicious"
]
  • 添加献汗、刪除、修改元素
dict[3] = "terrible"
dict[4] = "shit"
dict[5] = nil
  • 遍歷元素
for key in dict.keys {
    print("\(key) ---> \(dict[key]!)")
}
for value in dict.values {
    print(value)
}
for (index, value) in dict.enumerate() {
    print("\(index). \(value.0) ---> \(value.1)")
}

重要操作

  • 排序
  1. sort
  2. sortInPlace

說明:排序方法的參數(shù)是一個閉包(closure)王污,該閉包的作用是比較數(shù)組中兩個元素的大小罢吃。

let array = [23, 45, 12, 89, 98, 55, 7]
array.sort({ (one: Int, two: Int) -> Bool in
    return one < two
})
array.sort({ (one, two) in one < two })
array.sort({ one, two in one < two })
array.sort({ $0 < $1 })
array.sort { $0 < $1 }
array.sort(<)
  • 過濾
let array = [23, 45, 12, 89, 98, 55, 7]
// 篩選掉不滿足條件的數(shù)據(jù)
let newArray = array.filter { $0 > 50 }
print(newArray) // [89, 98, 55]
  • 映射
let array = [23, 45, 12, 89, 98, 55, 7]
// 通過映射對數(shù)據(jù)進(jìn)行變換處理
let newArray = array.map { $0 % 10 }
print(newArray)
  • 歸約
let array = [23, 45, 12, 89, 98, 55, 7]
let result = array.reduce(0, combine: +)
print(result)

函數(shù)和閉包

函數(shù)是獨(dú)立的可重復(fù)使用的功能模塊,如果程序中出現(xiàn)了大量的重復(fù)代碼昭齐,通常都可以將這部分功能封裝成一個獨(dú)立的函數(shù)尿招。在Swift中,函數(shù)是"一等公民"阱驾,可以作為類型來使用就谜,也就是說函數(shù)可以賦值給一個變量或常量,可以將函數(shù)作為函數(shù)的參數(shù)或者返回值里覆,還可以使用高階函數(shù)丧荐。

func 函數(shù)名([參數(shù)1: 類型, 參數(shù)2: 類型, ...]) [throws|rethrows] [-> 返回類型] {
    函數(shù)的執(zhí)行體
    [return 表達(dá)式]
}
  • 外部參數(shù)名
func foo(a a: Int,b: Int){
a + b
}
foo(a: 10,b: 11)
  • inout參數(shù)
func sum(inout a: Int, inout _ b: Int) {
     a + b
}
  • 可變參數(shù)列表
func m(a: Int...) -> Int{
    return a[0]
}


print(m(1,2,3))

閉包就是沒有名字的函數(shù)(匿名函數(shù))或者稱之為函數(shù)表達(dá)式(Lambda表達(dá)式),Objective-C中與之對應(yīng)的概念叫block喧枷。如果一個函數(shù)的參數(shù)類型是函數(shù)我們可以傳入一個閉包虹统;如果一個函數(shù)的返回類型是函數(shù)我們可以返回一個閉包;如果一個類的某個屬性是函數(shù)我們也可以將一個閉包表達(dá)式賦值給它隧甚。

{ ([參數(shù)列表]) [-> 返回類型] in 代碼 }

面向?qū)ο缶幊?OOP)

基本概念

對象:接收消息的單元车荔,對象是一個具體的概念。

類:對象的藍(lán)圖和模板呻逆,類是一個抽象概念夸赫。

消息:對象之間通信的方式,通過給對象發(fā)消息可以讓對象執(zhí)行對應(yīng)的操作來解決問題咖城。

四大支柱

抽象:定義類的過程就是一個抽象的過程茬腿,需要做數(shù)據(jù)抽象和行為抽象,數(shù)據(jù)抽象找到對象的屬性(保存對象狀態(tài)的存儲屬性)宜雀,行為抽象找到對象的方法(可以給對象發(fā)的消息)切平。

封裝:

  • 觀點(diǎn)1: 我們在類中寫方法其實(shí)就是在封裝API,方法的內(nèi)部實(shí)現(xiàn)可能會很復(fù)雜辐董,但是這些對調(diào)用這來說是不可見的悴品,調(diào)用只能看到方法有一個簡單清晰的接口。
  • 觀點(diǎn)2: 將對象的屬性和操作這些屬性的方法綁定在一起简烘。
  • 觀點(diǎn)3: 隱藏一切可以隱藏的實(shí)現(xiàn)細(xì)節(jié)苔严,只提供簡單清晰的接口(界面)。

繼承:指一個對象直接使用另一對象的屬性和方法

多態(tài):在面向?qū)ο笳Z言中孤澎,接口的多種不同的實(shí)現(xiàn)方式即為多態(tài)届氢。引用Charlie Calverts對多態(tài)的描述——多態(tài)性是允許你將父對象設(shè)置成為一個或更多的他的子對象相等的技術(shù),賦值之后覆旭,父對象就可以根據(jù)當(dāng)前賦值給它的子對象的特性以不同的方式運(yùn)作(摘自“Delphi4 編程技術(shù)內(nèi)幕”)退子。

三個步驟

  1. 定義類
  • 數(shù)據(jù)抽象
    • 存儲屬性
  • 行為抽象
    • 方法(寫到類里面的函數(shù)或者說跟對象綁定的行為就是方法)
      • 對象方法:給對象發(fā)的消息
      • 類方法:給類發(fā)的消息岖妄,與對象的狀態(tài)無關(guān)的方法
    • 計算屬性
  • 構(gòu)造器
    • 指派構(gòu)造器
    • 便利構(gòu)造器(convenience)
    • 必要構(gòu)造器(required)
  1. 創(chuàng)建對象
  2. 給對象發(fā)消息
class Triangle {
    var a: Double
    var b: Double
    var c: Double

    init(a: Double, b: Double, c: Double) {
        self.a = a
        self.b = b
        self.c = c
    }

    // 類方法(發(fā)給類的消息與對象狀態(tài)無關(guān))
    // 此處的static也可以換成class作用相同
    static func isValid(a: Double, _ b: Double, _ c: Double) -> Bool {
        return a + b > c && b + c > a && c + a > b
    }
    // 對象方法(發(fā)給對象的消息與對象狀態(tài)有關(guān))
    func perimeter() -> Double {
        return a + b + c
    }
}

let a = 1.0
let b = 2.0
let c = 3.0
// 在創(chuàng)建對象前先調(diào)用類方法判定給定的三條邊能否構(gòu)成三角形
// 類方法是發(fā)給類的消息所以不用創(chuàng)建對象直接通過類名調(diào)用
if Triangle.isValid(a, b, c) {
    let t = Triangle(a: a, b: b, c: c)
    // 對象方法是發(fā)給對象的消息要先創(chuàng)建對象才能調(diào)用
    print(t.perimeter())
}
else {
    print("無法創(chuàng)建三角形")
}

相關(guān)內(nèi)容

  • 枚舉

  • 結(jié)構(gòu)(體)

總結(jié):類和結(jié)構(gòu)的區(qū)別到底有哪些?什么時候應(yīng)該使用結(jié)構(gòu)寂祥?什么時候應(yīng)該使用類荐虐?

// 區(qū)別1: 結(jié)構(gòu)的對象是值類型, 類的對象是引用類型
// 值類型在賦值的時候會在內(nèi)存中進(jìn)行對象的拷貝
// 引用類型在賦值的時候不會進(jìn)行對象拷貝只是增加了一個引用
// 結(jié)論: 我們自定義新類型時優(yōu)先考慮使用類而不是結(jié)構(gòu)除非我們要定義的是一種底層的數(shù)據(jù)結(jié)構(gòu)(保存其他數(shù)據(jù)的類型)

// 引用類型的類
//let stu1 = Student1(name: "駱昊", age: 35)
//var stu3 = stu1     // 此處內(nèi)存中仍然只有一個學(xué)生對象
//stu3.name = "羅小號"
//stu3.age = 18
//print(stu1.name)
//print(stu1.age)
//
// 值類型的結(jié)構(gòu)
// 區(qū)別2: 結(jié)構(gòu)會自動生成初始化方法
//let stu2 = Student2(name: "駱昊", age: 35)
//var stu4 = stu2     // 此處內(nèi)存中會復(fù)制一個新的學(xué)生對象
//stu4.name = "王大錘"
//stu4.age = 18
//print(stu2.name)
//print(stu2.age)

// 在Swift中同名函數(shù)只要參數(shù)列表不同是可以共存的 這個叫函數(shù)的重載
func changeName(inout name: String) {
    name = "王大錘"
}

// 參數(shù)前面加var的做法在Swift 3中肯定是要廢掉的
func changeName(var stu: Student2) {
    stu.name = "王大錘"
}

// 計算機(jī)的硬件由五大部件構(gòu)成:
// 運(yùn)算器、控制器丸凭、存儲器福扬、輸入設(shè)備、輸出設(shè)備
// 運(yùn)算器 + 控制器 => CPU (中央處理器)
// 存儲器 => 內(nèi)存 (RAM - Random Access Memory)

// 程序員可以使用的內(nèi)存大致分為五塊區(qū)域:
// 棧 (stack) - 我們定義的局部變量/臨時變量都是放在棧上
//  - 特點(diǎn): 小贮乳、快
// 堆 (heap) - 我們創(chuàng)建的對象都是放在堆上的
//  - 特點(diǎn): 大忧换、慢
// 靜態(tài)區(qū) (static area)
//  - 數(shù)據(jù)段 - 全局量
//  - 只讀數(shù)據(jù)段 - 常量
//  - 代碼段 - 函數(shù)和方法

  • 擴(kuò)展(extension)
class Name {
    func a() {
        
    }
}

extension Name {
    func c () {
        
    }
}

let a = Name()
a.c()
  • 運(yùn)算符重載
func *(one: Fraction,two: Fraction) -> Fraction {
    
    return one.cheng(two)
}
  • 下標(biāo)運(yùn)算(subscript)

  • 訪問修飾符

    • private
    • internal
    • public

面向協(xié)議編程(POP)

協(xié)議

protocol 協(xié)議名[: 父協(xié)議1, 父協(xié)議2, ...] {
    // 方法的集合(計算屬性相當(dāng)于就是方法)
}
  1. 能力:
  2. 約定:
  3. 角色:

總結(jié)// 少用繼承多用協(xié)議
// 協(xié)議是方法的集合(計算屬性相當(dāng)于就是方法)
// 可以把看似不相關(guān)的對象的公共行為放到一個協(xié)議中
// 協(xié)議在swift開發(fā)中大致有三種作用
// 1. 能力 - 遵循了協(xié)議就意味著具備了某種能力
// 2. 約定 - 遵循了協(xié)議就一定要實(shí)現(xiàn)協(xié)議中的方法
// 3. 角色 - 一個類可以遵循多個協(xié)議恬惯,一個協(xié)議可以被多個類遵循向拆,遵循協(xié)議就意味著扮演了某種角色,遵循多個協(xié)議就意味著可以扮演多種角色
// swift中的繼承是單一繼承(一個類只能有一個父類)酪耳,如果希望讓一個類具備多重能力可以使用協(xié)議來實(shí)現(xiàn)(c++里面是通過多重繼承來實(shí)現(xiàn)的浓恳,這是一種非常狗血的做法)

依賴倒轉(zhuǎn)原則

  1. // 依賴倒轉(zhuǎn)原則(面向協(xié)議編程)
    // 1. 聲明變量的類型時應(yīng)該盡可能使用協(xié)議類型
    // 2. 聲明方法參數(shù)類型時應(yīng)該盡可能使用協(xié)議類型
    // 3. 聲明方法返回類型時應(yīng)該盡可能使用協(xié)議類型
  2. 依賴倒置原則(Dependence Inversion Principle)是程序要依賴于抽象接口,不要依賴于具體實(shí)現(xiàn)碗暗。簡單的說就是要求對抽象進(jìn)行編程颈将,不要對實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合言疗。

用協(xié)議實(shí)現(xiàn)委托回調(diào)

一個對象想做某件事情但是自身沒有能力做這件事情就可以使用委托回調(diào)晴圾,具體的步驟是:

  1. 設(shè)計一個協(xié)議,讓被委托方遵循協(xié)議并實(shí)現(xiàn)協(xié)議中的方法
  2. 委托方有一個屬性是協(xié)議類型的噪奄,通過該屬性可以調(diào)用協(xié)議中的方法

注意:委托方的協(xié)議類型的屬性通常是可空類型死姚,因?yàn)橐獙懗扇跻?weak)。

其他

  • 協(xié)議組合:protocol<協(xié)議1, 協(xié)議2, ...>
    1.// 協(xié)議的組合
    let array: [protocol <Flyable,Fightable>] = [
    // Bird(),
    Superman()
    // Airplane(),
    ]

  • 可選方法

  • 協(xié)議擴(kuò)展:對協(xié)議中的方法給出默認(rèn)實(shí)現(xiàn)

  1. protocol Fightable {
    func fight()
    }

// 協(xié)議擴(kuò)展 - 可以在協(xié)議擴(kuò)展中給協(xié)議中的方法提供默認(rèn)實(shí)現(xiàn)
// 也就是說如果某個類遵循了協(xié)議但是沒有實(shí)現(xiàn)這個方法就直接使用默認(rèn)實(shí)現(xiàn)
// 那么這個方法也就....
extension Fightable {
func fight() {
print("正在打架")
}
}

泛型

讓類型不再是程序中的硬代碼(hard code)勤篮,可以設(shè)計出更通用的代碼都毒。

  • 泛型函數(shù)
// 定義一個虛擬類型T, 調(diào)用函數(shù)時根據(jù)傳入的參數(shù)類型來決定T到底是什么
func mySwap<T>(inout a: T, inout _ b: T) {
    let temp = a
    a = b
    b = temp
}


  • 泛型類/結(jié)構(gòu)/枚舉
// Swift中的類、結(jié)構(gòu)和枚舉都可以使用泛型
struct Stack<T> {
    var data: [T] = []
    
    // 入棧
    mutating func push(elem: T) {
        data.append(elem)
    }
    
    // 出棧
    mutating func pop() -> T {
        return data.removeLast()
    }
    
    var isEmpty: Bool {
        get { return data.count == 0 }
    }
}

var stack = Stack<String>()
stack.push("hello")
stack.push("good")
stack.push("zoo")

while !stack.isEmpty {
    print(stack.pop())
}

相關(guān)知識

  • 泛型限定
// 泛型限定
// <T: Comparable>限定T類型必須是遵循了Comparable協(xié)議的類型
func bubbleSort<T: Comparable>(array: [T]) -> [T] {
    var newArray = array
    for i in 0..<newArray.count - 1 {
        var swapped = false
        for j in 0..<newArray.count - 1 - i {
            if newArray[j] > newArray[j + 1] {
                mySwap(&newArray[j], &newArray[j + 1])
                swapped = true
            }
        }
        if !swapped {
            break
        }
    }
    return newArray
}
  • where子句

錯誤處理

enum MyError: ErrorType {
    case A
    case B
    case C
}
  • throw
  • throws / rethrows
  • do
  • catch
  • try

邊角知識

  • ARC
  • 正則表達(dá)式
  • 嵌套類型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碰缔,一起剝皮案震驚了整個濱河市账劲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌金抡,老刑警劉巖瀑焦,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梗肝,居然都是意外死亡榛瓮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門统捶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榆芦,“玉大人柄粹,你說我怎么就攤上這事〈倚澹” “怎么了驻右?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長崎淳。 經(jīng)常有香客問我堪夭,道長,這世上最難降的妖魔是什么拣凹? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任森爽,我火速辦了婚禮,結(jié)果婚禮上嚣镜,老公的妹妹穿的比我還像新娘爬迟。我一直安慰自己,他們只是感情好菊匿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布付呕。 她就那樣靜靜地躺著,像睡著了一般跌捆。 火紅的嫁衣襯著肌膚如雪徽职。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天佩厚,我揣著相機(jī)與錄音姆钉,去河邊找鬼。 笑死抄瓦,一個胖子當(dāng)著我的面吹牛潮瓶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闺鲸,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼筋讨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摸恍?” 一聲冷哼從身側(cè)響起悉罕,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎立镶,沒想到半個月后壁袄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡媚媒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年嗜逻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缭召。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡栈顷,死狀恐怖逆日,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萄凤,我是刑警寧澤室抽,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站靡努,受9級特大地震影響坪圾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惑朦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一兽泄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漾月,春花似錦病梢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至栈雳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缔莲,已是汗流浹背哥纫。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痴奏,地道東北人蛀骇。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像读拆,于是被迫代替她去往敵國和親擅憔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,783評論 1 10
  • 132.轉(zhuǎn)換錯誤成可選值 通過轉(zhuǎn)換錯誤成一個可選值,你可以使用 try? 來處理錯誤檐晕。當(dāng)執(zhí)行try?表達(dá)式時,如果...
    無灃閱讀 1,244評論 0 3
  • 從小到大辟灰,我們都是活在別人的期望中个榕,不管是工作中做的事,還是學(xué)生時期讀的書都是被人安排的芥喇,這樣的我們實(shí)質(zhì)上就是一個...
    造價女俠閱讀 3,473評論 2 1
  • 這樣西采,耶和華獨(dú)自引導(dǎo)他,并無外邦神與他同在继控。 32:13 耶和華使他乘駕地的高處械馆,得吃田間的土產(chǎn)胖眷。又使他從磐石中咂...
    喜樂鹽泉閱讀 433評論 0 0
  • 我的大學(xué) 轉(zhuǎn)眼現(xiàn)在的我已經(jīng)是一個即將踏入大三的臘肉了,不再是剛剛來到學(xué)校時的那個青澀霹崎,對一切都很好奇的所謂的小學(xué)弟...
    濤書生閱讀 127評論 0 0