語(yǔ)言基礎(chǔ)
程序是指令的集合,寫(xiě)程序就是寫(xiě)一系列的指令去控制計(jì)算做我們想做的事情
編譯:將程序設(shè)計(jì)語(yǔ)言轉(zhuǎn)換成計(jì)算機(jī)能夠理解的機(jī)器語(yǔ)言或者某種中間代碼的過(guò)程
馮諾依曼體系結(jié)構(gòu)的計(jì)算機(jī)
1.使用二進(jìn)制
2.程序存儲(chǔ)執(zhí)行
變量和常量
定義變量和常量是為了保存數(shù)據(jù),變量和常量就是某種類型值得存儲(chǔ)空間。
var a:Int = 10
a = 100
var b : Int
b = 1000
var c = 1000
let d :Int = 10
//d = 100 //complier error
let e = 1000
let e = 1000
說(shuō)明:1.Swift有非常強(qiáng)大的類型推斷,所以定義變量或者常量時(shí)如果可以的話應(yīng)該直接使用類型推斷不用手動(dòng)指定類型;2.如果可以的話應(yīng)該竟可能使用常量而不是變量
語(yǔ)言元素
var a : Int = 10
關(guān)鍵字:有特殊含義的單詞
標(biāo)識(shí)符:給變量、常量、函數(shù)、類型、協(xié)議、枚舉、方法、屬性等起的名字
命名規(guī)則
1.字母(Unicode字符)、數(shù)字、下劃線,數(shù)字不能開(kāi)頭
2.大小寫(xiě)敏感(區(qū)分大小寫(xiě))
3.不能使用關(guān)鍵字做標(biāo)識(shí)符
4.使用駝峰命名法(命名變量、常量、函數(shù)、方法、屬性第一個(gè)單詞小寫(xiě),從第二個(gè)單詞開(kāi)始每個(gè)單詞首字母大寫(xiě):命名類、結(jié)構(gòu)、協(xié)議、枚舉每個(gè)單詞首字母都要大寫(xiě))
5.見(jiàn)名知意
6.命名私有的屬性和方法時(shí)以下劃線開(kāi)頭
運(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、ULLabel.self
分隔符:將不同的語(yǔ)言元素符號(hào)分開(kāi)
說(shuō)明:Swift中每個(gè)語(yǔ)句后面的分號(hào)是可寫(xiě)可不寫(xiě)的,寫(xiě)代碼時(shí)時(shí)盡量保證一行只有一個(gè)語(yǔ)句這樣就可以省略分號(hào)。
分支和循環(huán)
分支if -else
//判斷閏年
let year = 1980
if year%4==0&&year!=100||year%400==0{
print{"是閏年"}
}else{
print{"不是閏年"}
}
//分段函數(shù)
let x = 3.2
let y :Double
if x < -1 {
y=3*x-5
}else if x>3{
y=4*x+10
}else{
y=5
}
switch {case n:;default:}
let score = 60
let lv: String
switch score {
case 0..<20:lv = "新手"
case 20..<40:lv = "中級(jí)"
case 40..<60:lv = "高級(jí)"
default:lv = "大神"
}
print(lv)
循環(huán)求和:
1.直到型循環(huán)
repeat{ }while
var i = 1
var sum = 0
repeat{
sum += i
i += 1
}while i<=100
2.當(dāng)型循環(huán)while{ }
var i = 1
var sum = 0
while i<=100{
sum += i
i += 1
}
3.for循環(huán)for i in 1...n { }
var sum = 0
for i in 1...100{
sum += i
}
窮舉法:窮盡所有可能性直到能找到正確答案
"百錢(qián)百雞"問(wèn)題:
5元一公雞;3元一母雞;一元3小雞;
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)只")
}
}
}
說(shuō)明:在循環(huán)中可以使用break關(guān)鍵字來(lái)提前終止循環(huán),也可以使用continue關(guān)鍵字使循環(huán)直接進(jìn)入下一輪,但是應(yīng)該盡可能減少對(duì)break和continue的使用,因?yàn)樗麄儾粫?huì)讓你的程序變得更好。
綜合案列:Craps賭博游戲.
游戲規(guī)則:玩家搖兩顆骰子,如果第一次搖到11或7,玩家勝;如果搖出2點(diǎn),3或12,則莊家勝;其他點(diǎn)數(shù)繼續(xù),如果搖出7點(diǎn),莊家勝,搖出玩家第一次的點(diǎn)數(shù),玩家勝,其他繼續(xù)
func roll()->Int{
return Int(arc4random_uniform(6)+1)
}
let thyPoint = roll() + roll()
print("玩家搖出了\(thyPoint)點(diǎn)")
var needsGoOn = false
switch thyPoint {
case 7,11:print("玩家勝")
case 2,3,12:print("莊家勝")
default:
needsGoOn = true
}
while needsGoOn {
let currentPoint = roll()+roll()
print("玩家搖出了\(thyPoint)點(diǎn)")
if currentPoint == thyPoint {
print("玩家勝")
needsGoOn = false
}else if currentPoint == 7{
print("莊家勝")
needsGoOn = false
}
}
容器
數(shù)組
- 創(chuàng)建數(shù)組
let array1:[Int] = []
//let array1:Array<Int> = [] //等效
let array2 = [1,2,3,4,5,6]
let array3 = [Int](count:5,repeatedValue:0)
let 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
print(array3)
- 遍歷數(shù)組
1.方式1
for i in 0...array.count {
print(array[i])
}
2.方式2
for temp in array3 {
print(temp)
}
for temp in array3[1...3]{
print(temp)
}
說(shuō)明:for-in循環(huán)是一個(gè)只讀循環(huán),這也意味著在循環(huán)過(guò)程中不能進(jìn)行修改
3.方式3
for (i,temp) in array3.enumerate(){
if i == 1{
array3[i] = 1}
print("\(i).\(temp)")
}
提醒:操作數(shù)據(jù)時(shí)最重要的是不要越界訪問(wèn)元素。數(shù)組對(duì)象的count屬性表明了數(shù)組有多少個(gè)元素,那么有效的索引(下標(biāo))范圍0到count-1
數(shù)組中的元素也可以是數(shù)組,因此我們可以構(gòu)造多維數(shù)組。最常見(jiàn)的是二維數(shù)組,它相當(dāng)于是一個(gè)有行有列的數(shù)組,數(shù)組中的每個(gè)元素代表一行,該數(shù)組中的每個(gè)元素代表行里面的列。二維數(shù)組可以模擬顯示世界中的表格、數(shù)學(xué)上的矩陣、棋類游戲棋盤(pán)、格子類(2d)游戲的地圖。所以在實(shí)際開(kāi)發(fā)中使用非常廣泛。
//二維數(shù)組
func randomInt(min:UInt32,max:UInt32)->Int{
return Int(arc4random_uniform(max-min+1)+min)
}
let nameArray = ["關(guān)羽","張飛","趙云","馬超","黃忠"]
let coursesArray = ["語(yǔ)文","數(shù)學(xué)","英語(yǔ)"]
var scoresArray3 = [[Double]](count:nameArray.count, repeatedValue: [Double](count:coursesArray.count, repeatedValue: 0))
for i in 0..<scoresArray3.count{
for j in 0..<scoresArray3[i].count{
scoresArray3[i][j] = Double(randomInt(0,max:100))
}
}
for (index,array) in scoresArray3.enumerate(){
var sum = 0.0
for score in array{
sum += score
}
let avg = sum / Double(coursesArray.count)
print("\(nameArray[index])的平均成績(jī)?yōu)椋篭(avg)")
}
for i in 0..<coursesArray.count{
var sum = 0.0
for row in 0..<scoresArray3.count{
sum += scoresArray3[row][i]
}
let avg = sum / Double(nameArray.count)
print("\(coursesArray[i])的平均成績(jī)?yōu)?\(avg)")
}
集合
集合在內(nèi)存中是離散的,集合中的元素通過(guò)計(jì)算Hash Code(哈希碼或散列碼)來(lái)決定放在內(nèi)存中的什么位置,集合中不允許有重復(fù)元素。
- 創(chuàng)建集合
var set:Set<Int>=[1,2,3,4,5,1]
- 添加元素
set.insert(100)
- 刪除元素
set.remove(x)
//刪除哈希碼第一個(gè)
set.removeFirst()
set.removeAll()
- 集合的遍歷
for smap in set{
print(temp)
}
- 交集,并集,差集
var set1:Set<Int> = [1,3,5,7,8,4,9]
var set2:Set<Int> = [1,3,5,6]
set1.intersect(set2)//交
set1.union(set2)//并
set1.subtract(set2)//差
字典
字典是以鍵值對(duì)的方式保存數(shù)據(jù)的容器,字典中的元素是鍵值對(duì)的組合,通過(guò)鍵可以找到對(duì)應(yīng)的值。
-創(chuàng)建字典
var dict = [
1:"hello",
2:"good",
3:"wonderful",
5:"delicious"
]
- 添加元素和刪除元素,修改元素
dict[4] = "great"
dict.count
dict
dict[5] = nil//刪除直接賦空
//dict.removeValueForKey(5)過(guò)于復(fù)雜
dict[1] = "abc"http://修改
- 遍歷字典
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)--->\(value.1)")
}
重要操作
- 排序
1.sort
2.sortInPlace
說(shuō)明:排序方法的參數(shù)是一個(gè)閉包(closure)該閉包的作用是比較數(shù)組中兩個(gè)元素的大小
let array=[23,54,12,45,69,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{<}
- 過(guò)濾
let array=[23,54,12,45,69,7]
let newArray = array.filter{$0>50}
print(newArray)
- 映射
//通過(guò)映射對(duì)數(shù)據(jù)進(jìn)行變換處理
let array=[23,54,12,45,69,7]
let newArray = array.map{$0*$0}
print(newArray)
let newArray2 = array.mao{sqrt(Double($0))}
print(newArray2)
- 規(guī)約
let array=[23,54,12,45,69,7]
let newArray = array.filter{$0>50}
let newArray1 = newArray.map{$0*$0}
let result = newArray.reduce(0,combine:+)
print(result)
函數(shù)和閉包
函數(shù)是獨(dú)立的可重復(fù)使用的功能模塊,如果程序中出現(xiàn)了大量的重復(fù)代碼,通常都可以將這部分功能封裝成一個(gè)獨(dú)立的函數(shù)。在Swift中,函數(shù)是"一等公民"函數(shù)作為類型來(lái)使用,也就是說(shuō)函數(shù)可以賦值給一個(gè)變量或常量,可以將函數(shù)作為函數(shù)的參數(shù)或者返回值,還可以使用高階函數(shù)。
func 函數(shù)名([參數(shù)1:類型,參數(shù)2:類型,...])[throw|rethrows]->返回類型{
函數(shù)執(zhí)行體
[return 表達(dá)式]
}
- 外部參數(shù)名
- inout參數(shù)
- 可變參數(shù)列表
閉包就是沒(méi)有名字的函數(shù)或者稱之為函數(shù)表達(dá)式(Lambda表達(dá)式),Objective-c中與之對(duì)應(yīng)的概念叫block.如果一個(gè)函數(shù)的參數(shù)類型是函數(shù),我們可以傳入一個(gè)閉包,如果一個(gè)函數(shù)的返回類型是函數(shù)我們可以返回一個(gè)閉包。如果一個(gè)類的某個(gè)屬性是函數(shù)我們也可以將一個(gè)閉包表達(dá)式賦值給它。
{([參數(shù)列表]) [->返回類型]in 代碼}
面向?qū)ο缶幊蹋╫op)
基本概念
對(duì)象:接受消息的單元。(對(duì)象是一個(gè)具體的概念)
類:對(duì)象的藍(lán)圖和模塊,類是一個(gè)抽象概念。
消息:對(duì)象之間通信的方式,通過(guò)給對(duì)象發(fā)消息可以讓對(duì)象執(zhí)行對(duì)應(yīng)的操作來(lái)解決問(wèn)題
四大支柱
抽象:定義類的過(guò)程就是一個(gè)抽象過(guò)程,需要做數(shù)據(jù)抽象和行為抽象,數(shù)據(jù)抽象找到對(duì)象的屬性(保存對(duì)象狀態(tài)的存儲(chǔ)屬性),行為抽象找到對(duì)象的方法(可以給對(duì)象發(fā)消息)
封裝:
- 觀點(diǎn)1:我們?cè)陬愔袑?xiě)方法其實(shí)就是在封裝API,方法的內(nèi)部實(shí)現(xiàn)可能會(huì)很復(fù)雜,但是這些對(duì)調(diào)用者是不可用的,調(diào)用者只能看見(jiàn)方法有一個(gè)簡(jiǎn)單清晰的接口,這就是封裝。
- 觀點(diǎn)2:將對(duì)象的屬性和操作這些屬性的方法綁定在一起。
- 觀點(diǎn)3:隱藏一切可以隱藏的實(shí)現(xiàn)細(xì)節(jié),只提供簡(jiǎn)單清晰的接口(界面)。
繼承:從已有的類中創(chuàng)建出新類的過(guò)程,提供繼承信息的類父類(超類/基類),得到繼承信息的稱為子類(派生類/衍生類)。通常子類除了得到父類的繼承信息還會(huì)增加一些自己特有的東西
所有子類的能力一定比父類更強(qiáng)大。
繼承的意義在于子類可以復(fù)用父類的代碼并且增強(qiáng)系統(tǒng)現(xiàn)有的功能
多態(tài):重寫(xiě)
重載 - overload 子類將父類已有的方法重寫(xiě)實(shí)現(xiàn)一邊
重寫(xiě) - override
3個(gè)步驟
1.定義類
- 數(shù)據(jù)抽象
- 存儲(chǔ)屬性
- 行為抽象
- 方法(寫(xiě)到類里面的函數(shù)就是方法)
- 對(duì)象方法:給對(duì)象發(fā)消息,先創(chuàng)建對(duì)象再調(diào)用
- 類方法:給類發(fā)的消息,與對(duì)象的狀態(tài)無(wú)關(guān)的方法(例如,三角形提前判斷是否能構(gòu)成三角形),直接在類上打點(diǎn),調(diào)用。在方法前加STATIC或者class也可以
- 計(jì)算屬性
- 方法(寫(xiě)到類里面的函數(shù)就是方法)
- 構(gòu)造器
- 指派構(gòu)造器
- 便利構(gòu)造器(convenience)
- 必要構(gòu)造器 (required)
2.創(chuàng)建對(duì)象
3.給對(duì)象發(fā)消息
class
相關(guān)內(nèi)容
- 枚舉
- 結(jié)構(gòu)(體)
總結(jié)類和結(jié)構(gòu)的區(qū)別到底有哪些?什么時(shí)候使用結(jié)構(gòu)?什么時(shí)候該使用類?
- 擴(kuò)展(extension)
- 運(yùn)算符重載,要寫(xiě)在類外
- 下標(biāo)運(yùn)算(subscript)
- 訪問(wèn)修飾符
- Private
- internal
- public
面向協(xié)議編程(pop)
協(xié)議
protocol 協(xié)議名[:父協(xié)議1,父協(xié)議2,...]{
// 方法的集合(計(jì)算屬性相當(dāng)于方法)
}
1.能力
2.約定
3.角色
依賴倒轉(zhuǎn)原則
設(shè)計(jì)模式
- 代理回調(diào)
- 委托回調(diào)
- 一個(gè)對(duì)象想做某件事但是自身沒(méi)有能力做這件事情就可以使用委托回調(diào),集體步驟是:
- 1.設(shè)計(jì)一個(gè)協(xié)議,讓被委托方遵循協(xié)議并實(shí)現(xiàn)協(xié)議中的放法
- 2.委托方有一個(gè)屬性是協(xié)議類型的,通過(guò)該屬性可以調(diào)用協(xié)議中的方法
- 委托方的協(xié)議類型的屬性通常是可空類型,因次要寫(xiě)成weak引用
其他
- 協(xié)議組合:protocal<協(xié)議1,協(xié)議2,...>
- 可選方法
- 協(xié)議拓展
泛型
讓類型不再是程序中的硬代碼(hard code),可以設(shè)計(jì)出更通用的代碼
泛型函數(shù)
泛型類/結(jié)構(gòu)/枚舉
相關(guān)知識(shí)
- 泛型限定
- where子句
錯(cuò)誤處理
enum MyError:ErrorType {
case A
case B
case C
}