Swift簡(jiǎn)介
作者:Chris Lattner
Swift 2010年7月開始設(shè)計(jì),1年時(shí)間完成基本架構(gòu)弱左,經(jīng)歷4年開發(fā)期于WWDC 2014 蘋果2014年開發(fā)者大會(huì)發(fā)布壶愤,用于撰寫OS X和iOS應(yīng)用程序讶泰。
特點(diǎn):
語(yǔ)法簡(jiǎn)單叫胖,代碼簡(jiǎn)潔藐吮,使用方便勃黍。
可與OC混合使用肺樟。
提供了類似JAVA的命名空間缴罗,泛型宝恶,運(yùn)算符重載乘综。
提供了很多方便的工具方法憎账,例如元組、guard卡辰、可變參數(shù)等等
Swift從2014年發(fā)布開始胞皱,到現(xiàn)在已經(jīng)更新到4.0版本,Swift替代OC的路走的比我想象的快很多九妈,我認(rèn)為Swift在日漸趨于穩(wěn)定的狀態(tài)下反砌,代碼風(fēng)格不會(huì)再有太大的變化,并且Xcode對(duì)Swift語(yǔ)法錯(cuò)誤的檢測(cè)糾錯(cuò)敏感度很高萌朱,幫助我們很快找到語(yǔ)法錯(cuò)誤并修改宴树。Swift的語(yǔ)法簡(jiǎn)單靈活給我們帶來(lái)了很多方便,只要是我們認(rèn)為可以省略的代碼基本上都可以省略晶疼,但是這對(duì)新手可能不是太友好酒贬,看起來(lái)差異很大的代碼,其實(shí)是省略掉一部分內(nèi)容轉(zhuǎn)化而來(lái)的翠霍。這就需要很熟悉Swift的語(yǔ)法锭吨,并且對(duì)那些代碼可以省略有清晰的認(rèn)識(shí)。
常量和變量
Swift中定義標(biāo)識(shí)符必須明確指明該標(biāo)識(shí)符是常量還是變量寒匙。常量和變量將名字(標(biāo)識(shí)符)和一個(gè)特定類型的值關(guān)聯(lián)起來(lái)零如。
使用let定義變量,表示該值不可再被更改
使用var定義變量 锄弱,表示將來(lái)可以被修改為不同的值
語(yǔ)法格式:
// let / var 標(biāo)識(shí)符名稱 : 標(biāo)識(shí)符類型 = 賦值
let score : Double = 89.5
var age : Int = 20
// Swift中如果一行只有一條語(yǔ)句的時(shí)候考蕾,那么語(yǔ)句結(jié)束時(shí)的;可以省略
注意:
- 在開發(fā)中,我們一般優(yōu)先使用常量会宪,只有發(fā)現(xiàn)標(biāo)識(shí)符需要修改時(shí)辕翰,在使用變量,這樣做防止我們?cè)诓幌M敌薷牡那闆r下狈谊,在其他地方被修改喜命。
- 常量的本質(zhì):標(biāo)識(shí)符指向的內(nèi)存地址不可以被修改沟沙,但是可以通過(guò)內(nèi)存地址找到對(duì)應(yīng)的對(duì)象,修改對(duì)象內(nèi)部的屬性壁榕。
- 省略:上面例子中
:Double 和 :Int
是可以省略的矛紫,事實(shí)上,我們也不需要經(jīng)常使用類型標(biāo)注牌里,如果在定義一個(gè)變量或常量的時(shí)候就初始化一個(gè)值颊咬,那么Swift就可以推斷出這個(gè)變量或常量的類型, 可以通過(guò)option + 鼠標(biāo)左鍵來(lái)查看標(biāo)識(shí)符類型牡辽。 - 標(biāo)識(shí)符名稱喳篇,也就是變量和常量的名字不能包含空白字符、數(shù)學(xué)符號(hào)态辛、箭頭麸澜、保留的或者無(wú)效的Unicode碼位、連線和制表符奏黑,也不能以數(shù)字開頭炊邦。
輸出變量和常量
Swift中使用print()
打印變量和常量中的值
print("hello swift")
// 當(dāng)需要輸出變量或常量的時(shí)候,可以直接使用字符串插值的方式把變量名或常量名當(dāng)做占位符加入到字符串當(dāng)中熟史,Swift會(huì)用常量或變量的當(dāng)前值來(lái)替換這些占位符
// 通過(guò)將常量或變量放入()中并在前面加上\將其轉(zhuǎn)義
let version : Double = 4.0
print("hello swift \(version)")
類型安全和類型推到
Swift是一門類型安全的語(yǔ)言馁害,類型安全的語(yǔ)言可以讓我們清楚的知道值得類型,幫助我們規(guī)避很多錯(cuò)誤蹂匹。Swift會(huì)在編譯代碼的時(shí)候進(jìn)行類型檢查碘菜,如果我們錯(cuò)誤的將不匹配的類型進(jìn)行賦值,編譯器就會(huì)標(biāo)記為錯(cuò)誤限寞。
同時(shí)炉媒,如果沒有為值進(jìn)行類型聲明,Swift會(huì)通過(guò)檢查我們給變量賦的值并在編譯階段就自動(dòng)推斷出值得合適的類型昆烁,這個(gè)過(guò)程叫做類型推導(dǎo)吊骤。
我們可以通過(guò)option + 鼠標(biāo)左鍵來(lái)查看標(biāo)識(shí)符類型。
let score = 89.5
var age = 20
// 編譯器會(huì)在賦值時(shí)自動(dòng)根據(jù)其值推斷出 score為Double類型静尼,age為Int類型
let sum = 55.5 + 30
// 甚至編譯器會(huì)推斷出算式的值得類型為Double
基本運(yùn)算
Swift中相同類型的之間才可以進(jìn)行運(yùn)算白粉,Swift中沒有類似OC中的隱式類型轉(zhuǎn)換,所以當(dāng)兩個(gè)變量類型不同時(shí)鼠渺,需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換鸭巴。前面提到過(guò)Swift是一門強(qiáng)類型語(yǔ)言,即使Int8類型和Int類型也不能直接進(jìn)行運(yùn)算拦盹,同樣需要強(qiáng)制轉(zhuǎn)換類型才可以鹃祖。
強(qiáng)制類型轉(zhuǎn)換 Int(標(biāo)識(shí)符a) 、Double(標(biāo)識(shí)符b)
let n = 10
let x : Int8 = 5
let m = 10.5
let result = Double(n) + m // Int轉(zhuǎn)化為Double
let result1 = Int(m) + n // Double轉(zhuǎn)化為Int
let retule2 = Int(x) + n // Int8 與 Int進(jìn)行運(yùn)算同樣需要轉(zhuǎn)化
除了不同類型之間運(yùn)算需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換外普舆,Swift中其他基本運(yùn)算符與OC中一樣恬口,這里不再贅述校读,同時(shí)Swift中還添加了一些非常方便的運(yùn)算符
閉區(qū)間運(yùn)算符
(a...b)
,定義了從a到b的一組范圍祖能,并且包含a和b歉秫。要求 a <= b
半開區(qū)間運(yùn)算符(a..<b)
,定義了從a到b但不包括b的區(qū)間养铸,要求a<=b雁芙,當(dāng)a=b時(shí)那么返回的區(qū)間為空
單側(cè)區(qū)間運(yùn)算符[2...]
,一般用于數(shù)組中钞螟,例如list[2...]
即表示從list數(shù)組索引2開始一直到結(jié)束兔甘。注意這時(shí)2必須小于數(shù)組的count,否則編譯器將會(huì)報(bào)錯(cuò)
當(dāng)然也可以寫成[...2]
表示從0開始到2的索引鳞滨,[..<2]
表示從0開始到1的索引
Swift作為強(qiáng)制類型語(yǔ)言還添加了 !
強(qiáng)制解包運(yùn)算符和??
合并空值運(yùn)算符這些在之后講到可選類型的時(shí)候再做詳細(xì)解釋
邏輯分支
Swift提供了多種多樣的控制流語(yǔ)句洞焙,使我們?cè)谌粘J褂弥锌梢愿鶕?jù)不同的情況進(jìn)行使用,除了 if while之外Swift提供了guard語(yǔ)句來(lái)應(yīng)對(duì)需要對(duì)多個(gè)條件進(jìn)行判斷的情況太援,使代碼邏輯顯得更加清晰
if 條件語(yǔ)句
Swift中 if 后面的條括號(hào)可以省略掉闽晦,同時(shí)需要注意的是扳碍,Swift中沒有像OC中非0(nil)即真的判斷方式提岔,也就是說(shuō)在Swift中我們必須給出明確的判斷條件
let score = 88
if score > 0 {
print("score > 0")
}
if score != 0 {
print("score != 0")
}
// 這里不能像OC中 if (a) {} 即可判斷a是否為0,Swift中必須給出明確的判斷條件
if條件判斷語(yǔ)句同OC中一樣笋敞,只不過(guò)if后面括號(hào)去掉也許會(huì)讓我們稍有些不習(xí)慣碱蒙,不過(guò)很快就會(huì)熟悉
// if else
if score < 0 || score > 100 {
print("不合理分?jǐn)?shù)")
}else if score < 60 {
print("不及格")
}else if score >= 60{
print("及格")
}
guard ,guard的使用與if非常類似夯巷,可以同if進(jìn)行無(wú)縫轉(zhuǎn)化赛惩,為了提高代碼的可讀性,我們可以把guard看做一個(gè)看門人趁餐,不符合條件的統(tǒng)統(tǒng)不許通過(guò)喷兼,最后通過(guò)的也就是我們想要的結(jié)果
let idCard = true
let ticket = true
func Ontrain (idCard : Bool , ticket : Bool) {
// 判斷有沒有帶身份證
guard idCard else {
print("沒有帶身份證,不可以乘車")
return
}
// 判斷有沒有車票
guard ticket else {
print("沒有車票后雷,不可以乘車")
return
}
print("身份證和車票都帶了季惯,可以乘車")
// 滿足以上所有條件才可以 使用場(chǎng)景:滿足所有條件才可以達(dá)成某些功能
}
Switch , Swift對(duì)Switch進(jìn)行了進(jìn)行了大大的增強(qiáng),使其擁有其他語(yǔ)言中沒有的特性
- switch后面的()可以省略
- case語(yǔ)句結(jié)束臀突,可以不加break勉抓,系統(tǒng)默認(rèn)幫我們加上了break,如果希望case結(jié)束時(shí)產(chǎn)生穿透候学, 去除break效果需要加上 fallthrough藕筋。
- 在每條case中必須包含至少一條可執(zhí)行語(yǔ)句,不能為空梳码。
- case語(yǔ)句后面可以判斷多個(gè)條件隐圾,每個(gè)條件之間用逗號(hào)隔開伍掀,如果任何一個(gè)條件匹配了,則會(huì)執(zhí)行case下的語(yǔ)句
- Switch可以判斷多種類型翎承,包括 浮點(diǎn)型硕盹,字符串類型,區(qū)間類型叨咖,元組
- Switch可以將匹配到的值臨時(shí)綁定為一個(gè)變量或者一個(gè)常量瘩例,來(lái)給case中的執(zhí)行語(yǔ)句使用
- 同時(shí)可以在case語(yǔ)句后面添加額外的where判斷
- Switch可以被打上標(biāo)簽循環(huán)使用
Switch基本使用
let sex = 0
switch sex {
case 0:
print("M")
break // 可省略
case 1:
print("F")
fallthrough // 如果想要產(chǎn)生穿透
default:
print("?")
}
Switch語(yǔ)句后面判斷多個(gè)條件
switch sex {
case 0,1: // 任何一個(gè)條件匹配了,就會(huì)執(zhí)行case下的語(yǔ)句
print("正常")
default:
print("???")
}
既然Switch語(yǔ)句可以判斷多個(gè)條件甸各,那么一定可以在case后面進(jìn)行區(qū)間匹配
let score = 88
switch score {
case 0..<60:
print("不及格")
case 60..<80:
print("及格")
case 80...100:
print("優(yōu)秀")
default:
print("不合理分?jǐn)?shù)")
}
Switch中也可以判斷多種類型垛贤,字符串類型,元組趣倾,浮點(diǎn)型
// 這里用元組舉例
let point = (1,1) // 類型為(Int,Int)的元組
switch point {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0): // 如果不想匹配元組中的某一個(gè)值聘惦,可以用_代替
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2): // 元組中使用區(qū)間匹配
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// prints "(1, 1) is inside the box"
Switch可以將匹配到的值臨時(shí)綁定為一個(gè)變量或者一個(gè)常量,來(lái)給case中的執(zhí)行語(yǔ)句使用
let personInfo = (name : "xx_cc" , age : 20)
switch personInfo {
case (let x , 1..<18):
print("未成年的人有\(zhòng)(x)")
case (let x , 18..<100):
print("成年的人有\(zhòng)(x)")
default:
print("沒有匹配的人")
}
// print 成年的人有xx_cc
Switch在case語(yǔ)句后面添加額外的where判斷
let personInfo = (name : "xx_cc" , age : 20)
switch personInfo {
case (let x , 1..<18) where x == "xx_cc": // 只是舉例儒恋,并沒有意義
print("未成年的人有\(zhòng)(x)")
case (let x , 18..<40) where x == "xx_cl": // 只是舉例善绎,并沒有意義
print("成年的人有\(zhòng)(x)")
default:
print("沒有匹配的人")
}
// print "沒有匹配的人\n"
給語(yǔ)句打標(biāo)簽
var times = 0
timeLoop : while times < 10 {
times += 1
switch times {
case 6:
break timeLoop
case 4:
continue timeLoop
default:
print("default")
}
}
// print : default default default default
// 這里我們給while循環(huán)打上timeLoop標(biāo)簽,可以發(fā)現(xiàn)诫尽,times等于1...3時(shí)打印了三遍defult禀酱,當(dāng)times等于4時(shí),continue結(jié)束了當(dāng)前while循環(huán)并開始下一次循環(huán)牧嫉,times等于5然后打印第四遍default剂跟,times等于6時(shí)bread timeLoop結(jié)束了while循環(huán)不在進(jìn)行打印。
循環(huán)語(yǔ)句
Swift中循環(huán)語(yǔ)句與OC中相同酣藻,for 曹洽,while ,repeat while循環(huán)。使用方法也與OC中基本相同
for i in 0..<10 {
print(i)
}
// 在 Swift中如果一個(gè)變量/常量暫時(shí)不會(huì)使用辽剧,那么可以使用_來(lái)代替送淆,_不會(huì)占用內(nèi)存空間
for _ in 0...10 {
print("hello Swift")
}
repeat while也就是OC中的do while
var m = 0
while m < 10 {
m += 1
print(m)
}
// repeat 無(wú)論是否成立都要先走一次
repeat {
m -= 1
print(m)
} while m > 0
集合
Swift 提供了三種主要的集合類型,所謂的數(shù)組怕轿、合集還有字典偷崩,用來(lái)儲(chǔ)存值的集合。數(shù)組是有序的值的集合撤卢。合集是唯一值的無(wú)序集合环凿。字典是無(wú)序的鍵值對(duì)集合。
Swift中的集合都是泛型集合放吩,也就是說(shuō)集合需要明確存儲(chǔ)的值得類型智听,保證我們不會(huì)意外的插入一個(gè)錯(cuò)誤類型的值到集合中去,同時(shí)保證我們可以從集合中取回確定類型的值。
數(shù)組
數(shù)組以有序的方式來(lái)儲(chǔ)存相同類型的值到推。相同類型的值可以在數(shù)組的不同地方多次出現(xiàn)考赛。
Swift中的數(shù)組是Array類型的,不想OC中區(qū)分NSArray與NAMutableArray莉测,而是通過(guò)我們創(chuàng)建方式的不同來(lái)定義數(shù)組
不可變數(shù)組 :let修飾
可變數(shù)組 :var修飾
定義數(shù)組語(yǔ)法
// Array類型 <>里表示數(shù)組中存放的數(shù)據(jù)類型
let array : Array<String> = ["a","b","c"] // 不可變數(shù)組不可操作
// 數(shù)組類型簡(jiǎn)寫 推薦使用簡(jiǎn)寫寫法颜骤,更加簡(jiǎn)單清晰
let array : [String] = ["a","b","c"]
// 創(chuàng)建空數(shù)組
var arrayM2 = Array<String>()
// 同樣可以進(jìn)行簡(jiǎn)寫
var arrayM : [String] = Array()
var arrayM1 = [String]()
/*
* 同時(shí)數(shù)組還為我們提供了初始化方法創(chuàng)建
* repeating:表示數(shù)組存儲(chǔ)對(duì)應(yīng)類型的默認(rèn)值
* count:表示數(shù)組內(nèi)元素的個(gè)數(shù)
*/
var arr = Array(repeating: "a", count: 5)
對(duì)可變數(shù)組的基本操作
// 獲取數(shù)組元素個(gè)數(shù)
let count = arrayM.count
// 同時(shí)也可以使用isEmpty Bool值屬性 來(lái)對(duì)數(shù)組是否為空進(jìn)行快速判斷
if arrayM.isEmpty {
}
// 1. 添加元素
arrayM.append("xx_cc")
// 也可以使用 +=運(yùn)算符在數(shù)組末尾添加新的同類型元素
arrayM += ["xx","cc"]
// 使用 insert方法添加元素到指定位置
arrayM.insert("js", at: 1)
// 刪除元素
arrayM.remove(at: 0) // 返回被刪除的元素
arrayM.removeAll() // 刪除所有的
arrayM.removeLast() // 刪除最后一個(gè)
arrayM.removeFirst() // 刪除第一個(gè)
// 提取元素
let name = arrayM[0]
// 修改元素
arrayM[0] = "xx_cc"
// 也可以使用區(qū)間類型修改多個(gè)元素
arrayM[2...3] = ["haha","xixi"]
需要注意的是,同OC一樣捣卤,當(dāng)我們?cè)L問(wèn)或者修改一個(gè)超出數(shù)組元素個(gè)數(shù)的值將會(huì)引發(fā)崩潰忍抽。
數(shù)組的遍歷
同OC一樣,我們可以使用 for in 來(lái)遍歷整個(gè)數(shù)組中的值
for item in arrayM {
print(item)
}
// 如果我們想要拿到數(shù)組中每個(gè)元組的值以及它的索引董朝,我們可以使用enumerated()方法來(lái)返回?cái)?shù)組中每一個(gè)元素的元組鸠项,元組中包含了元素的索引和值
for (index , item) in arrayM.enumerated(){
print(index)
print(item)
}
集合
Swift中集合的類型是Set,同OC中NSSet一樣子姜,集合是將同一類型且不重復(fù)的值無(wú)序地儲(chǔ)存在一個(gè)集合當(dāng)中祟绊。
定義集合語(yǔ)法
// 使用 Set<Element>創(chuàng)建并初始化一個(gè)集合
var letters = Set<Int>()
// 注意Set沒有同數(shù)組一樣對(duì)應(yīng)的簡(jiǎn)寫方式
// 也可以通過(guò)數(shù)組來(lái)創(chuàng)建集合
var name: Set<String> = ["cc", "xx", "xx_cc"]
集合的訪問(wèn)和修改
// 通過(guò)count來(lái)訪問(wèn)集合內(nèi)元素的個(gè)數(shù)
print(name.count)
// 也可以通過(guò) isEmpty快速判斷count屬性是否為0
if name.isEmpty {
print("As far as music goes, I'm not picky.")
}
// 通過(guò)insert為集合新增加一個(gè)元素
name.insert("enen")
// 刪除集合中的元素
if let nameInfo = name.remove("cc") {
print("\(nameInfo)")
}
// 如果集合中有cc這個(gè)元素那么就刪除它,并且返回被刪除的元素哥捕,如果沒有就返回nil
// 我們這里使用 if let 來(lái)對(duì)返回的值進(jìn)行判斷牧抽,如果集合中存在被刪除的參數(shù),那么返回值不為nil遥赚,然后就會(huì)執(zhí)行大括號(hào)里面的內(nèi)容扬舒,如果集合中不存在該參數(shù),那么就會(huì)返回nil鸽捻,大括號(hào)中的內(nèi)容就不會(huì)執(zhí)行
// 使用contains()方法檢查集合中是否包含了特定的元素
if name.contains("xx") {
print("xx is in set")
}
集合的遍歷
for nameStr in name {
print("\(nameStr)")
}
// 可以通過(guò)使用 sorted方法將合集的元素進(jìn)行排序
for nameStr in name..sorted() {
print("\(nameStr)")
}
集合基本操作
Swift提供了很多便捷的方法讓我們對(duì)集合進(jìn)行基本操作來(lái)獲取兩個(gè)集合相交的集合或者其他等等呼巴。
- 使用
intersection(_:)
方法來(lái)創(chuàng)建一個(gè)只包含兩個(gè)集合共有值的新合集泽腮。- 使用
symmetricDifference(_:)
方法來(lái)創(chuàng)建一個(gè)只包含兩個(gè)集合各自有的非共有值的新集合御蒲。- 使用
union(_:)
方法來(lái)創(chuàng)建一個(gè)包含兩個(gè)集合所有值的新集合;- 使用
subtracting(_:)
方法來(lái)創(chuàng)建一個(gè)兩個(gè)集合當(dāng)中不包含某個(gè)集合值的新合集诊赊。
集合基本操作圖例- 使用“相等”運(yùn)算符 ( == )來(lái)判斷兩個(gè)集合是否包含有相同的值厚满;
- 使用 isSubset(of:) 方法來(lái)確定一個(gè)集合的所有值是被某合集包含;
- 使用 isSuperset(of:)方法來(lái)確定一個(gè)集合是否包含某個(gè)合集的所有值碧磅;
- 使用 isStrictSubset(of:) 或者 isStrictSuperset(of:)方法來(lái)確定是個(gè)集合是否為某一個(gè)集合的子集或者超集碘箍,但并不相等;
- 使用 isDisjoint(with:)方法來(lái)判斷兩個(gè)集合是否擁有完全不同的值鲸郊。
字典
Swift中字典的類型是 Dictionary丰榴,同樣是泛型集合,Int Double類型均為結(jié)構(gòu)體秆撮,都可以放入數(shù)組和字典中四濒。
字典的定義
let 定義不可變字典
var 定義可變字典
// 字典也用[]表示,編譯器會(huì)自動(dòng)區(qū)分[]中是一個(gè)個(gè)元素(數(shù)組)還是鍵值對(duì)(字典)
let dic : Dictionary<String , Any> = ["string" : "xx_cc", "age" : 18 , "height" : 1.88]
// 與數(shù)組一樣,同樣可以對(duì)字典進(jìn)行簡(jiǎn)寫
let dic2 : [String : Any] = ["string" : "xx_cc", "age" : 18 , "height" : 1.88] // 推薦 這種寫法更簡(jiǎn)便一些
//定義可變字典 var 修飾
var dicM = Dictionary <String ,Any> ()
var dicM1 = [String : Any]()
// 與數(shù)組一樣盗蟆,如果你用一致類型的字典字面量初始化字典戈二,就不需要寫出字典的類型了
var dicName = ["xx_cc":"xx","xx_cl":"cl"]
對(duì)可變字典的基本操作
// 同數(shù)組一樣字典也擁有count屬性和isEmpty屬性來(lái)得到字典的元素個(gè)數(shù)和快速判斷字典元素個(gè)數(shù)是否為0
給字典添加元素
dicM["name"] = "xx_cc"
dicM["age"] = 18
dicM["height"] = 1.88
// 刪除元素
dicM.removeValue(forKey: "name") // 如果刪除成功則返回被刪除的值,如果字典沒有這個(gè)鍵值對(duì)則返回nil
dicM.removeAll()
// 我們也可以使用下標(biāo)腳本語(yǔ)法給一個(gè)鍵賦值 nil來(lái)從字典當(dāng)中移除一個(gè)鍵值對(duì)
dicM["name"] = nil
// 修改元素 字典會(huì)自動(dòng)索引字典中沒有相同的key喳资,如果沒有就添加觉吭,如果有就修改其值
dicM["name"] = "xx_ccha"
// updateValue的功能同上,同樣會(huì)增加或修改元素的值
// 如果updateValue是更新已經(jīng)存在鍵的值仆邓,則會(huì)返回原來(lái)舊值的可選類型
// 如果updateValue為字典新增加了一個(gè)元素鲜滩,則返回nil
dicM.updateValue("xx_ccha", forKey: "name")
遍歷字典
// 遍歷字典中所有的key
for key in dic.keys {
print(key)
}
// 遍歷字典中所有的value
for value in dic.values {
print(value)
}
// 遍歷字典中所有的key - value
for (key,value) in dic{
print(key, value)
}
// 拿到所有key 或value組成的數(shù)組
let keyArr = [String](dict.keys)
let valueArr = [String](dict.values)
// 我們可以通過(guò)遍歷其中一個(gè)字典,為第二個(gè)字典賦值节值,來(lái)合并兩個(gè)字典
let dicStr : [String : Any] = ["name" : "cl" , "age" : 18]
var dicStr2 : [String : Any] = ["name":"xx","height" : 1.88 , "phone" : "110"]
for (key , value) in dicStr {
dicStr2[key] = value
}
同樣绒北,Swift 的 Dictionary類型是無(wú)序的。要以特定的順序遍歷字典的鍵或值察署,則需要使用sorted()
方法闷游。
元組
元組是Swift中新添加的可以將多個(gè)值合并成單一的復(fù)合型的值,并且元組內(nèi)的值可以是任何類型贴汪,且不必是同一類型脐往。
任何類型的排列都可以被用來(lái)創(chuàng)建一個(gè)元組,他可以包含任意多的類型扳埂。元組非常方便的幫助我們解決了數(shù)組和字典的缺陷业簿。在Swift中經(jīng)常使用。
元組的創(chuàng)建
// 元組創(chuàng)建寫法一
let infoTuple = ("xx_cc",18,1.88)
// 可以通過(guò)從零開始的索引訪問(wèn)元組中的單獨(dú)元素
let tupleName = infoTuple.0
// 寫法二 為元組中單個(gè)元素命名
let infoTuple1 = (name:"xx_cc", age:18, height:1.88)
let nameLength = infoTuple1.name.characters.count
// 如果只想取出元組中部分?jǐn)?shù)據(jù)阳懂,不想要取出的可以用_代替
let (tupleName2, age2, _) = infoTuple1
print("我叫\(zhòng)(tupleName2)今年\(age2)")
// 寫法三 一一對(duì)應(yīng)
let (name,age,height) = ("cl",18,1.88)
print(name)
??????可選類型
Swift中只有可選類型才能被賦值為nil梅尤,其他類型都不能賦值為nil
OC中當(dāng)一個(gè)值不在使用時(shí),我們可以將它賦值為0(基本數(shù)據(jù)類型)或者賦值為nil(對(duì)象類型)岩调,但是在Swift中巷燥,nil是一個(gè)特殊的類型,同String号枕,Int相同缰揪。而Swift是一門強(qiáng)類型語(yǔ)言,類型不匹配無(wú)法賦值葱淳。所以只有可選類型才能被賦值為nil钝腺。被可選類型修飾的值則表示該值有可能為nil。
可選類型的定義
// 首先我們嘗試給String變量賦值為nil編譯器報(bào)錯(cuò)
// Nil cannot initialize specified type 'String'
// var name : String = nil
// 定義可選類型 Optional表示可選類型 泛型集合
var name : Optional<String> = nil
// 簡(jiǎn)寫 String赞厕?表示可選類型的string
var name1 : String? = nil
// 問(wèn)號(hào)明確了它儲(chǔ)存的值是一個(gè)可選項(xiàng)艳狐,意思就是說(shuō)它可能包含某些 String 值,或者為nil皿桑。
// 給可選類型進(jìn)行賦值
name1 = Optional("xx_cc") // 方式一
name1 = "xx_cc" // 方式二 編譯器會(huì)自動(dòng)加上 Optional()
我們通過(guò)option查看name為String?可選類型同時(shí)當(dāng)我們?cè)陬愔袆?chuàng)建暫時(shí)不需要使用的變量的時(shí)候毫目,定義為可選類型并且不提供默認(rèn)值喷斋,變量會(huì)被自動(dòng)設(shè)置為nil。
對(duì)可選類型進(jìn)行取值
print(name1)
// 取出可選類型中的值 可選類型! --> 強(qiáng)制解包
print(name1!)
// print Optional("xx_cc")
// print xx_cc
可以發(fā)現(xiàn)直接打印name1輸出 Optional("xx_cc")可選類型蒜茴,并不是我們想要拿到的字符串星爪,使用!對(duì)可選類型進(jìn)行強(qiáng)制解包,可以拿到可選類型中的值粉私。但是我們只有非常確定可選類型有值才可以使用強(qiáng)制解包顽腾,一旦可選類型為nil,強(qiáng)制解包程序就會(huì)立即崩潰诺核,這在開發(fā)中是非常危險(xiǎn)的
所以我們可以在使用的時(shí)候優(yōu)先對(duì)可選類型進(jìn)行判斷
// 判斷可選類型不為nil抄肖,然后才強(qiáng)制解包
if name1 != nil {
print(name1!)
}
但是我們?cè)陂_發(fā)中會(huì)大量的使用可選類型,如果每一個(gè)都需要進(jìn)行判斷就會(huì)非常麻煩窖杀,所以Swift推出可選綁定語(yǔ)法漓摩,該語(yǔ)法用于可選類型,使我們使用可選類型更加方便入客。
可選綁定語(yǔ)法
if let tempName = name1 {
print(tempName)
}
可選綁定會(huì)優(yōu)先判斷name1是否有值管毙,如果沒有值,則直接不執(zhí)行{}中的內(nèi)容桌硫,如果name有值夭咬,那么系統(tǒng)會(huì)自動(dòng)對(duì)可選類型進(jìn)行解包,并且將解包后的結(jié)果賦值給前面的tempName铆隘。
同時(shí)為了方便卓舵,并且避免同一個(gè)變量有多個(gè)名字,我們可以使用相同的名字進(jìn)行命名膀钠,在大括號(hào)內(nèi)直接使用相同的變量名即可掏湾。
if let name1 = name1{
print(name1)
}
類型轉(zhuǎn)化
我們通過(guò)as將實(shí)例轉(zhuǎn)化為一種類型
將String轉(zhuǎn)化為NSString
let str = "askkdsfjksdfffff" as NSString
str.substring(to: 6)
通過(guò) as? 將實(shí)例轉(zhuǎn)化為可選類型
let dict : [String : Any] = ["name":"xx_cc" , "age" :18]
let tempName = dict["name"]
print(tempName!)
// 通過(guò)as?轉(zhuǎn)成可選類型 這里將 any 類型 轉(zhuǎn)成 string類型
// as? 轉(zhuǎn)成的類型是一個(gè)可選類型,系統(tǒng)會(huì)自動(dòng)判斷tempName是否可以轉(zhuǎn)成String類型肿嘲,如果可以轉(zhuǎn)成融击,那么獲取字符串,如果轉(zhuǎn)化不成功睦刃,則返回nil
let name = tempName as? String
if let name = name {
print(name)
}
if let name = dict["name"] as? String {
print(name)
}
通過(guò) as! 轉(zhuǎn)成具體類型
// 注意:如果轉(zhuǎn)化不成功則程序會(huì)崩潰
// 建議:如果確定轉(zhuǎn)化成功再用as! 進(jìn)行轉(zhuǎn)化
let tempName1 = dict["name"]
let name1 = tempName1 as! String
使用as?轉(zhuǎn)化的name為String?類型砚嘴,使用as!轉(zhuǎn)化的name1為String類型
可選類型不僅增加了代碼的可讀性十酣,并且使Swift代碼更加嚴(yán)謹(jǐn)和安全涩拙。
文中如果有不對(duì)的地方歡迎指出。我是xx_cc耸采,一只長(zhǎng)大很久但還沒有二夠的家伙兴泥。