Swift 是一門靜態(tài)的強(qiáng)類型語(yǔ)言。它以簡(jiǎn)單荧降、干凈接箫、可讀性好等特點(diǎn)著稱。
1朵诫、 為什么是靜態(tài)語(yǔ)言列牺?
首先靜態(tài)語(yǔ)言比之動(dòng)態(tài)語(yǔ)言,更具有安全性拗窃。它不允許類型之間自動(dòng)的進(jìn)行轉(zhuǎn)換瞎领,必須要顯示的轉(zhuǎn)換。Swift是類型安全的随夸,它會(huì)在編譯的時(shí)候就檢查你的代碼九默,任何類型不匹配時(shí)都會(huì)報(bào)錯(cuò)。這使得編程人員能夠盡快捕獲并盡可能早地在開(kāi)發(fā)過(guò)程中修正錯(cuò)誤宾毒。但是驼修,這并不意味著你必須指定每一個(gè)常量和變量所聲明的類型。如果不指定你需要的類型诈铛,Swift使用類型推導(dǎo)來(lái)指定出相應(yīng)的類型乙各。類型推導(dǎo)使編譯器在編譯的時(shí)候通過(guò)你提供的初始化值自動(dòng)推導(dǎo)出特定的表達(dá)式的類型。類型推導(dǎo)使Swift比起C或Objective-C只需要更少的類型聲明語(yǔ)句幢竹。常量和變量仍然顯式類型耳峦,但大部分指定其類型的工作Swift已經(jīng)為你完成了。當(dāng)你聲明一個(gè)常量或變量并給出初始值類型的時(shí)候焕毫,類型推導(dǎo)就顯得特別有用蹲坷。這通常是通過(guò)給所聲明的常量或變量賦常值來(lái)完成的。
例如:你要聲明一個(gè)用戶名字符串常量邑飒,并為他賦值叫“json”.
let userName = "son"
不必指定什么類型循签,在編譯時(shí)會(huì)通過(guò)類型推導(dǎo)的機(jī)制將常量userName 自動(dòng)設(shè)為 賦的值的類型。
2疙咸、什么叫強(qiáng)類型語(yǔ)言县匠?
即變量或者常量,必須要先定義然后才能使用撒轮,否則會(huì)報(bào)錯(cuò)乞旦。
好了 ,言歸正傳腔召,下面給大家介紹下Swift 中的字符串和集合
字符與字符串
Swift集百家之長(zhǎng),吸收了主流語(yǔ)言Java杆查、C、C++等的好的特性,所以它功能十分強(qiáng)大,今天我們就來(lái)看看它強(qiáng)大的字符串臀蛛。
首先亲桦,我們帶著這樣幾個(gè)問(wèn)題去了解、理解swift的字符串浊仆。
1客峭、swift字符串怎么初始化的?
2抡柿、swift字符串長(zhǎng)度可變嗎舔琅?
3、swift字符串是指針洲劣,還是實(shí)際的值备蚓?
4课蔬、swift有哪些特性?
下面郊尝,我來(lái)一一解答這些問(wèn)題二跋。
(1) swift 字符串的初始化有2種方式,這兩種方式的結(jié)果都是一樣的流昏。我們來(lái)初始化一個(gè)空字符串扎即。
var str1 = "" // 第一種方式
var str2 = String() // 第二種方式
var str3 = "hello word" // 當(dāng)初始化一個(gè)非空字符串時(shí),可以這樣
(2) swift字符串長(zhǎng)度是可變的,當(dāng)然這只針對(duì)于用var 定義的字符串况凉,用let定義的字符串常量是不可變的谚鄙。正因?yàn)檫@個(gè)特性,它可以和其他字符刁绒,字符串通過(guò)符號(hào)“ = ”闷营、“ += ”組合成新的字符串。
var str1 = "hello"
var str2 = "world"
var str3:Character = "!" // 這是定義字符的方式
var strs1 = str1 + str2 // 結(jié)果為“hello word”
(3)swift字符串 是實(shí)際的值膛锭,不是指針粮坞。當(dāng)把字符串變量賦值給另一個(gè)值,它原來(lái)的值不變初狰。當(dāng)把字符串變量當(dāng)作參數(shù)傳遞時(shí)莫杈,它也是一個(gè)實(shí)際的值。
var str1 = "你好"
var str2 = str1 // 這時(shí),str1的值還是“你好”
由此可見(jiàn),它不是指針,是一個(gè)實(shí)際的值奢入。
(4)swift字符串有哪些特性筝闹?它的比較機(jī)制,驗(yàn)證機(jī)制腥光,遍歷機(jī)制关顷,轉(zhuǎn)換機(jī)制,組合機(jī)制武福,都是它的特性议双。
a、比較機(jī)制捉片。字符串之間的比較是可以分多樣的平痰。
它比較完全相等時(shí),用“==”來(lái)連接伍纫;
它比較前綴相等時(shí)宗雇,給定一個(gè)字符串前綴,然后用要比的字符串莹规,調(diào)用hasPrefix方法赔蒲,參數(shù)為給定的前綴;
它比較后綴相等時(shí),給定一個(gè)字符串后綴舞虱,然后用要比的字符串欢际,調(diào)用hasSuffix方法,參數(shù)為給定的后綴砾嫉。
舉個(gè)例子幼苛,我們學(xué)校在開(kāi)興趣班,要統(tǒng)計(jì)各個(gè)興趣班的人數(shù)有多少焕刮?用這個(gè)就可以很容易的找出來(lái)。
let students = [
"iOS,謝明,s3sj101",
"android,胡軍,s3jn95",
"iOS,都美君,s3jn95",
"技術(shù)支持,高小龍,s3jn92",
"數(shù)據(jù)庫(kù),阿斯,s3jn92",
"數(shù)據(jù)庫(kù),封劍,s3j101"
]
var ios = 0 // 定義ios班的人數(shù)
var android = 0 // 定義android班的人數(shù)
var technical = 0 // 定義技術(shù)支持班的人數(shù)
var database = 0 // 定義數(shù)據(jù)庫(kù)班的人數(shù)
for student in students {
if student.hasPrefix("iOS") {
ios++
}
if student.hasPrefix("android") {
android++
}
if student.hasPrefix("技術(shù)支持") {
technical++
}
if student.hasPrefix("數(shù)據(jù)庫(kù)") {
database++
}
}
print("報(bào)iOS班的人數(shù):\(ios)") // 2
print("報(bào)android班的人數(shù):\(android)") // 1
print("技術(shù)支持班的人數(shù):\(technical)") // 1
print("數(shù)據(jù)庫(kù)班的人數(shù):\(database)") // 2
如果我們要統(tǒng)計(jì)各個(gè)原班有多少人墙杯,可以這樣做:
let students = [
"ios,謝明,s3sj101",
"android,胡軍,s3jn95",
"ios,都美君,s3jn95",
"技術(shù)支持,高小龍,s3jn92",
"數(shù)據(jù)庫(kù),阿斯,s3jn92",
"數(shù)據(jù)庫(kù),封劍,s3j101"]
var s3jn95 = 0 // 定義s3jn95班的人數(shù)
var s3jn92 = 0 // 定義s3jn92班的人數(shù)
var s3j101 = 0 // 定義s3j101班的人數(shù)
for student in students {
if student.hasSuffix("s3jn95") {
s3jn95++
}
if student.hasSuffix("s3jn92") {
s3jn92++
}
if student.hasSuffix("s3j101") {
s3j101++
}
}
print("s3sj95班的人數(shù):\(s3jn95)") // 2
print("s3jn92班的人數(shù):\(s3jn92)") // 2
print("s3j101班的人數(shù):\(s3j101)") // 1
b:驗(yàn)證機(jī)制配并。判斷一個(gè)字符串是不是為空,我們可以用isEmpty屬性獲取
var str = ""
if str.isEmpty {
print("str是空字符串") // 執(zhí)行結(jié)果:str是空字符串
}
else {
print("str是非空字符串")
}
c:遍歷機(jī)制高镐。我們知道溉旋,字符串是有字符組成,swift可以遍歷字符串中的每個(gè)字符嫉髓。
var str = "HelloWorld"
for i in str.characters {
print(i)
}
執(zhí)行結(jié)果會(huì)把每個(gè)字符遍歷出來(lái)观腊。
d:轉(zhuǎn)換機(jī)制。它還支持字符串的大小寫(xiě)轉(zhuǎn)換算行。通過(guò)uppercaseString和lowercaseString屬性可以做到梧油,我們來(lái)看看:
var str = "helloWorld"
var upper = ""
var lower = ""
upper = str.uppercaseString // 定義一個(gè)存放轉(zhuǎn)化為大寫(xiě)后的變量
lower = str.lowercaseString // 定義一個(gè)存放轉(zhuǎn)化為小寫(xiě)后的變量
print(upper)
print(lower)
然后分別輸出就行了 ,很簡(jiǎn)單吧州邢。儡陨。。
e:組合機(jī)制.組合機(jī)制是它很大的一個(gè)亮點(diǎn)量淌,它的長(zhǎng)度是可變的骗村,因此也是可以組合的。這給我們的開(kāi)發(fā)帶來(lái)很大的遍歷呀枢,是我們開(kāi)發(fā)者的福音哦胚股。
這里就不舉例了,他們之間可以通過(guò)“+”裙秋、“+=”琅拌、也可以通過(guò)一個(gè)合法的表達(dá)式生成新的字符串。最后残吩,它還可以計(jì)算字符串的總長(zhǎng)度财忽,
需要用到的方法是:countElements。參數(shù)為要計(jì)算的字符串本身泣侮。
獲取字符串的長(zhǎng)度
var str = "helloWorld"
// 獲取字符集合,再獲取集合的count屬性
let count = str.characters.count // 10
兩個(gè)字符串的拼接
let str1 = "Hello"
let str2 = "World"
let str3 = str1 + str2 //HelloWorld
字符串和其他數(shù)據(jù)類型的拼接
let name = "why"
let age = 18
let info = "my name is \(name),age is \(age)" // my name is why,age is 18
字符串的格式化
// 比如時(shí)間: 03:04
let min = 3
let second = 4
let time = String(format: "%02d:%02d", arguments:[min,second]) // "03:04"
字符串的截取
// 1.簡(jiǎn)單的方式是將String轉(zhuǎn)成NSString來(lái)使用,在標(biāo)識(shí)符后加 as NSString即可
let myStr = "HelloWorld"
var subStr = (myStr as NSString).substringFromIndex(5) // return "World"
subStr = (myStr as NSString).substringToIndex(5) // return "Hello"
subStr = (myStr as NSString).substringWithRange(NSRange(location: 5, length: 5)) // return "World"
// 2.Swift截取方式
let str = "MyPlayground"
// 截取開(kāi)始位置
let fromindex = str.startIndex.advancedBy(2)
let header = str.substringToIndex(fromindex) // retrun "My"
// 截取結(jié)束位置
let toindex = str.endIndex.advancedBy(-6)
let footer = str.substringToIndex(toindex) // return "MyPlay"
// 截取中間的字符串
let range = Range(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-6))
let middle = str.substringWithRange(range) // return "Play"
數(shù)組
Swift提供了3種主要的集合類型即彪,array,set,dictionary隶校。本節(jié)介紹array漏益。
數(shù)組是存儲(chǔ)有序的相同類型的集合,相同的值可以多次出現(xiàn)在不同的位置深胳。
注意:
Swift的Array類型橋接Foundation的NSArray類
數(shù)組類型簡(jiǎn)單語(yǔ)法
Swift數(shù)組類型完整寫(xiě)作Array<Element>绰疤,Element是數(shù)組允許存儲(chǔ)值的合法類型,你也可以簡(jiǎn)單的寫(xiě)作[Element]舞终。盡管兩種形式在功能上是一樣的轻庆, 但是我們推薦較短的那種,而且在本文中都會(huì)使用這種形式來(lái)使用數(shù)組敛劝。
創(chuàng)建數(shù)組
// 創(chuàng)建一個(gè)空數(shù)組
var someInts = [Int]()
print("someInts is type [Int] with \(someInts.count) items.") // return:0
需要注意的是余爆,someInts變量的類型在初始化時(shí)推斷為一個(gè)int類型,或者如果上下文已經(jīng)提供類型信息夸盟,例如一個(gè)函數(shù)參數(shù)或者一個(gè)已經(jīng)定義好類型的常量或者變量蛾方,我們也可以直接寫(xiě)作 [],而不需要加Int上陕。
someInts.append(3) // someInts now contains 1 value of type Int
someInts = [] // someInts is now an empty array, but is still of type [Int]
創(chuàng)建一個(gè)帶有默認(rèn)值的數(shù)組
Swift 中的Array類型還提供了一個(gè)可以創(chuàng)建特定大小并且所有數(shù)據(jù)設(shè)置為相同的默認(rèn)值的構(gòu)造方法桩砰。我們可以把準(zhǔn)備加入數(shù)組的item數(shù)量(count)和適當(dāng)類型的初始值(repeatedValue)傳入數(shù)組構(gòu)造函數(shù):
// 創(chuàng)建一個(gè)帶有默認(rèn)值的數(shù)組
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)
2個(gè)數(shù)組合并為一個(gè)數(shù)組
通過(guò)+來(lái)實(shí)現(xiàn)2個(gè)數(shù)組合為一個(gè)新數(shù)組
// 2個(gè)數(shù)組合并為一個(gè)數(shù)組
// 通過(guò)+來(lái)實(shí)現(xiàn)2個(gè)數(shù)組合為一個(gè)新數(shù)組
//anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]
var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)
// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
var shoppingList:[String] = ["Eggs","Milk"]
// 這里說(shuō)明shoppingList是一個(gè)存儲(chǔ)String類型的數(shù)組變量,而且只能存儲(chǔ)String類型的值。它還可以簡(jiǎn)單的寫(xiě)作
var shoppingList2 = ["Eggs","Milk"]
數(shù)組的訪問(wèn)和修改
// 獲取數(shù)組數(shù)據(jù) - 下標(biāo)法
// firstItem is equal to "Eggs
var firstItem = shoppingList[0]
// 添加數(shù)據(jù) - 使用append(_:)方法在數(shù)組的結(jié)尾處添加一條新的數(shù)據(jù)释簿。
shoppingList.append("Flour")
// 使用+=也可以向數(shù)組中添加若干條新的數(shù)據(jù)
// shoppingList now contains 4 items
shoppingList += ["Baking Powder"]
// shoppingList now contains 7 items
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// 使用insert(_:atIndex:)在指定位置插入新的數(shù)據(jù)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
shoppingList.insert("Maple Syrup", atIndex: 0)
// 修改數(shù)組 - 下標(biāo)法修改其中一項(xiàng)值
shoppingList[0] = "Six eggs"
// 也可以修改指定范圍內(nèi)的值
// shoppingList now contains 6 items
shoppingList[4...6] = ["Bananas", "Apples"]
// removeAtIndex(_:)刪除數(shù)組中指定位置的數(shù)據(jù)
// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string”
let mapleSyrup = shoppingList.removeAtIndex(0)
shoppingList
我們可以通過(guò)數(shù)組的方法和屬性來(lái)訪問(wèn)和修改數(shù)組亚隅,或者下標(biāo)語(yǔ)法。 使用數(shù)組的只讀屬性count來(lái)獲取數(shù)組的count辕万。
使用isEmpty判斷數(shù)組是否為空枢步。
我們不可以通過(guò)下標(biāo)法來(lái)在數(shù)組的末尾處添加新的數(shù)據(jù),因?yàn)閕ndex超出數(shù)組長(zhǎng)度后是不合法的渐尿,會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤
如果你像刪除數(shù)組中最后一條數(shù)據(jù)醉途,那么你應(yīng)該使用removeLast(),而不應(yīng)該使用removeAtIndex()砖茸,因?yàn)樗挥貌樵償?shù)組的長(zhǎng)度隘擎。
數(shù)組的遍歷
你可以使用for-in'循環(huán)來(lái)遍歷數(shù)組
// 你可以使用for-in'循環(huán)來(lái)遍歷數(shù)組
for item in shoppingList {
print(item)
}
如果我們同時(shí)需要每個(gè)數(shù)據(jù)項(xiàng)的值和索引值,可以使用全局enumerate函數(shù)來(lái)進(jìn)行數(shù)組遍歷凉夯。enumerate返回一個(gè)由每一個(gè)數(shù)據(jù)項(xiàng)索引值和數(shù)據(jù)值組成的鍵值對(duì)組货葬。我們可以把這個(gè)鍵值對(duì)組分解成臨時(shí)常量或者變量來(lái)進(jìn)行遍歷:
for (index,value) in shoppingList.enumerate() {
print("Item \(index+1):\(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas”
字典
字典是一種存儲(chǔ)相同類型多重?cái)?shù)據(jù)的存儲(chǔ)器。每個(gè)值(value)都關(guān)聯(lián)獨(dú)特的鍵(key)劲够,鍵作為字典中的這個(gè)值數(shù)據(jù)的標(biāo)識(shí)符震桶。和數(shù)組中的數(shù)據(jù)項(xiàng)不同,字典中的數(shù)據(jù)項(xiàng)并沒(méi)有具體順序征绎。
字典寫(xiě)作Dictionary<Key, Value>蹲姐。也可以寫(xiě)作[Key: Value]
// 創(chuàng)建空字典
// namesOfIntegers is an empty [Int: String] dictionary
var namesOfIntegers = [Int:String]()
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers[16] = "sixteen"
namesOfIntegers
// namesOfIntegers is once again an empty dictionary of type [Int: String]
namesOfIntegers = [:]
namesOfIntegers
// 創(chuàng)建字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports
// 類型推斷
var airports2 = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports2
airports["LHR"] = "London Heathrow"
airports
// 訪問(wèn)和修改
// Prints "The old value for DUB was Dublin.
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was \(oldValue).")
}
airports
// removeValueForKey(_:)刪除鍵值對(duì)
if let removedValue = airports.removeValueForKey("DUB") {
print("The removed airport's name is \(removedValue).")
} else {
print("The airports dictionary does not contain a value for DUB.")
}
airports
// 遍歷
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
// YYZ: Toronto Pearson
// LHR: London Heathrow
for airportCode in airports.keys {
print("Airport code: \(airportCode)")
}
// Airport code: YYZ
// Airport code: LHR
for airportName in airports.values {
print("Airport name: \(airportName)")
}
// Airport name: Toronto Pearson
// Airport name: London Heathrow
// count返回字典的鍵值對(duì)數(shù)
// isEmpty判斷字典是否為空
Sets
Sets是存儲(chǔ)無(wú)序的相同類型的值,你可以在順序不重要的情況下使用Sets來(lái)替代數(shù)組,或者當(dāng)你需要同一個(gè)值在集合中只出現(xiàn)一次時(shí)柴墩。
Sets類型語(yǔ)法
寫(xiě)作Set<Element>忙厌,Element是sets允許存儲(chǔ)的類型
// 創(chuàng)建并初始化一個(gè)空的set
var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// Prints "letters is of type Set<Character> with 0 items.
// 如果可以推斷出它元素的類型也可以寫(xiě)作
letters = []
// 通過(guò)數(shù)組字面量來(lái)創(chuàng)建set
var favoriteGenres:Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
// 或者(因?yàn)榭梢酝茢酁閟et<String>)
var favoriteGenres2:Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres2 has been initialized with three initial items
// 訪問(wèn)和修改
// count方法返回set的數(shù)據(jù)項(xiàng)數(shù)目
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres.
// isEmpty判斷set是否為空
// contains(_:)檢查set對(duì)象是否包含特定的數(shù)據(jù)。
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// Prints "It's too funky in here.
// 添加新數(shù)據(jù)項(xiàng)
// insert(_:)向現(xiàn)有的set對(duì)象添加新的數(shù)據(jù)
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items
// 刪除已有的數(shù)據(jù)項(xiàng)
// remove(_:)向現(xiàn)有的set對(duì)象刪除已有的數(shù)據(jù)
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// Prints "Rock? I'm over it.
// 遍歷set
// 使用for in語(yǔ)句遍歷set
for genre in favoriteGenres {
print("\(genre)")
}
// Classical
// Jazz
// Hip hop
// set無(wú)序存儲(chǔ)數(shù)據(jù),使用sort()可以按到升序排序江咳。
// intersect(_:)創(chuàng)意一個(gè)包含兩set對(duì)象共有的數(shù)據(jù)的新的Set對(duì)象
// exclusiveOr(_:)創(chuàng)意一個(gè)不包含兩set對(duì)象共有的數(shù)據(jù)的新的Set對(duì)象
// union(_:)創(chuàng)意一個(gè)包含兩set對(duì)象所有的數(shù)據(jù)的新的Set對(duì)象
// subtract(_:)創(chuàng)意一個(gè)只存在其中一個(gè)已有的set類型數(shù)據(jù)的新的Set對(duì)象
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersect(evenDigits).sort()
// []
oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]
oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]
// ==操作符比較2個(gè)set的值是否全部相同
let houseAnimals: Set = ["??", "??"]
let farmAnimals: Set = ["??", "??", "??", "??", "??"]
let cityAnimals: Set = ["??", "??"]
houseAnimals.isSubsetOf(farmAnimals) // true
farmAnimals.isSupersetOf(houseAnimals) // true
farmAnimals.isDisjointWith(cityAnimals) // true