主要記錄一下可能容易遺忘的知識點(diǎn)
1.沒有隱式類型轉(zhuǎn)換
所有的轉(zhuǎn)換需要顯示的進(jìn)行,例如:
var widthStr = "The width is "
var widthValue = 15
var width = widthStr + String(widthValue)
var num = 12 // num默認(rèn)為Int類型
var num2 = 12.0 // num2默認(rèn)為Double類型
2.把值插入字符串的更簡單方法
let apple = 2
let banana = 3
let total = "I have \(apple + banana) pieces of fruits"
3.多行字符串
let multiLineStr = """
I am ABC
I like DEF
"""
4.除了數(shù)組 字典也用方括號組來創(chuàng)建
let dict = [
"key1" : "value1",
"key2" : "value2"
]
let value1 = dict["key1"]
5.創(chuàng)建空數(shù)組或者空字典
- 指定元素類型
let arr = [String]()
let dict = [String:Float]()
- 數(shù)組或者字典內(nèi)元素類型已知 可以用如下方式聲明其為空
arr = []
dict = [:]
6.for in循環(huán)不再強(qiáng)制需要給for in語句寫括號 但是循環(huán)體的花括號還是需要的
其他例如if判斷、while、repeat-while也是如此
for str in strArr {
print(str)
}
var n = 1
while n < 10 {
n = n * 2
}
7.if語句的判斷條件現(xiàn)在必須為布爾表達(dá)式 而不能是 if score 這種格式
布爾值的類型為Bool
有true
和false
這兩個(gè)常量值 和OC中的YES
和NO
不同
可以使用let/var
和if
來對可能為nil
的值進(jìn)行判斷 如果值存在就將值賦予給一個(gè)常量或者變量 并執(zhí)行if
內(nèi)的語句 這個(gè)稱為可選項(xiàng)綁定
var optionalName : String? = "Tom"
// var optionName : String? = nil
var greeting = "Hello"
if let name = optionName {
greeting = "Hello \(name)!"
}
8.也可以使用?易茬?返回可選類型的默認(rèn)值
??
對可選項(xiàng)進(jìn)行判斷 如果存在值就返回這個(gè)值 否則返回運(yùn)算符后面的值
var a : Int?
var b = a ?? 10
9.switch語句不需要再寫break了 會自動退出當(dāng)前case
let vegetable = "red pepper"
switch vegetable {
case "celery":
print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
print("Is it a spicy \(x)?")
default:
print("Everything tastes good in soup.")
}
10.遍歷字典更方便了 只需要提供一對存儲鍵值對的變量就行了
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
print(largest)
11.使用..<創(chuàng)建一個(gè)不包含最大值的區(qū)間 使用...創(chuàng)建一個(gè)包含最大值的區(qū)間
其實(shí)相當(dāng)于聲明了數(shù)組
for i in 0..<4 {
print(i) //輸出為0 1 2 3
}
for i in 0...4 {
print(i) //輸出為0 1 2 3 4
}
12.函數(shù)的聲明和調(diào)用
func greet(person:String, day:String) -> String {
return "Hello, \(person), today is \(day)!"
}
greet(person:"Bob", day:"Tuesday")
->
表示返回值類型
調(diào)用時(shí)候要帶上實(shí)參標(biāo)簽
也可以在申明的時(shí)候用_
取消標(biāo)簽
或者聲明另一個(gè)標(biāo)簽名稱
func greet(_ person:String, on day:String) -> String {
return "Hello, \(person), today is \(day)!"
}
greet("Bob", on:"Tuesday")
13.使用元組可以讓函數(shù)返回一個(gè)復(fù)合值
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
} else if score < min {
min = score
}
sum += score
}
return (min, max, sum)
}
14.函數(shù)可以用...接受多個(gè)參數(shù) 并放到一個(gè)數(shù)組里面
func printManyNumber(numbers : Int...) {
for num in numbers {
print(num)
}
}
printManyNumber(numbers: 1,2,3,4) // 傳遞參數(shù)的時(shí)候用逗號隔開
15.函數(shù)可以內(nèi)嵌函數(shù) 內(nèi)嵌函數(shù)可以訪問外部函數(shù)的變量
func foo(a : Int) -> Int {
a = a * 2
func bar() {
a = a + 5
}
bar()
return a
}
foo(5)
16.函數(shù)可以作為函數(shù)的返回值
func getFunc() -> ((Int) -> Int) {
func increase(num : Int) -> Int {
return num + 1
}
return increase
}
var increaseFunc = getFunc()
increaseFunc(1)
17.函數(shù)也可以作為函數(shù)的參數(shù)傳遞
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)
18.閉包
- 閉包的一般表達(dá)式語法為:
{ (parameter) -> returnType in
statements
}
- 舉個(gè)例子(當(dāng)函數(shù)的最后一個(gè)參數(shù)為閉包的時(shí)候 可以省略函數(shù)的括號)
var userNames = ["Tom", "Bob", "Jack"]
userNames.sort{ (name1:String, name2:String) ->Bool in
return name1 < name2
}
- 由于
sort函數(shù)
的函數(shù)參數(shù)的類型已知(即(String, String) -> Bool
)所以閉包可以簡化 省略參數(shù)的括號和返回類型
userNames.sort{ name1, name2 in
return name1 < name2
}
- 單行表達(dá)式閉包可以通過省略
return
關(guān)鍵字來隱式返回單行表達(dá)式的結(jié)果
userNames.sort{ name1, name2 in name1 < name2 }
- 內(nèi)聯(lián)閉包可以省略參數(shù)名直接用參數(shù)順序
$0
,$1
,$2
調(diào)用
userNames.sort{ $0 < $1 }
- 閉包默認(rèn)是不允許逃逸的 如果允許逃逸 需要用@escaping聲明
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
那么何時(shí)閉包允許逃逸呢阀溶?比如處理異步回調(diào)的時(shí)候腻脏,異步函數(shù)本身是直接返回的,但是異步處理需要異步操作完成之后才進(jìn)行银锻,這時(shí)候的閉包就需要允許逃逸永品。
- 讓閉包 @escaping 意味著你必須在閉包中顯式地引用 self
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure()
}
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
someFunctionWithNonescapingClosure { x = 200 }
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
// Prints "200"
completionHandlers.first?()
print(instance.x)
// Prints "100"
19.子類重寫父類的方法 需要使用override關(guān)鍵字 不使用會造成編譯器報(bào)錯
class Son : Father {
var k
init( j: String , k: Int) {
super.init(j)
self.k = k
}
override func foo() {
print("This is son's foo func")
}
}
let instance = Son()
instance.foo()
20.類型別名
類型別名可以為已經(jīng)存在的類型定義了一個(gè)新的可選名字。用 typealias
關(guān)鍵字定義類型別名击纬。
typealias AudioSample = UInt32
let maxAudioLength = AudioSample.max
21.可選項(xiàng)
var optionalStr : String? = "abc" // 聲明一個(gè)可選項(xiàng) optionalStr有可能沒有值(nil在swift里表示沒有值 對所有類型有效)
let strVal = optionalStr! // 在可選項(xiàng)變量后面加上一個(gè)!表示強(qiáng)制展開可選項(xiàng) 如果可選項(xiàng)沒有值會報(bào)錯
let assumedStr : String! = "I have value" // 隱式展開可選項(xiàng) 表示assumedStr被訪問的時(shí)候一定有值 不需要做檢查
22.錯誤處理
- 當(dāng)一個(gè)函數(shù)可能拋出錯誤時(shí)鼎姐,使用
throws
關(guān)鍵字
func canThrowError() throws {
// statements
}
- 當(dāng)調(diào)用一個(gè)可能拋出錯誤的函數(shù)時(shí),使用
try
關(guān)鍵字
do {
try canThrowError()
// 未拋出錯誤
} catch {
// 拋出錯誤
}
23.斷言和先決條件
斷言只在debug模式下檢查 先決條件則都會檢查
在不滿足條件的時(shí)候 兩者都會終止程序的運(yùn)行
let age = -1
assert(age >= 0, "Age must be greater than 0")
precondition(index > 0, "Index must be greater than zero.")
24.字符串是值類型
也就是說作為參數(shù)傳入的時(shí)候更振,傳遞的是這個(gè)字符串的拷貝炕桨,在函數(shù)里修改字符串對原來的字符串沒有任何影響
25.Character類型也用雙引號表示
let charA : Character = "A"
let str : String = "ABCDE"
for char in str {
print(char)
}
str.append(charA) // 用append方法可以給字符串后拼接Character
26.可以以Unicode標(biāo)量形式聲明一個(gè)字符
let dollarString : Character = "/u{24}" // 24代表Unicode標(biāo)量碼位為U+0024的美元符號"$"
有些特殊字符可以由一個(gè)單一的Unicode標(biāo)量或者幾個(gè)Unicode標(biāo)量組合表示 但是在Swift中,都用Character這個(gè)類型表示這個(gè)字符
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ?
// eAcute is é, combinedEAcute is é
使用count屬性獲取一個(gè)字符串里面Character的數(shù)量
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafe is 4"
word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in café is 4"
27.字符串的索引
- 字符串不能直接通過整數(shù)值索引來訪問 需要借助幾個(gè)特殊的屬性和函數(shù)
-
.startIndex
返回字符串第一個(gè)Character的位置,.endIndex
返回字符串最后一個(gè)Character之后
的位置肯腕,也就是說.endIndex
不是一個(gè)合法的索引 - 使用
index(before:)
和index(after:)
方法來訪問給定索引的前后谋作。要訪問給定索引更遠(yuǎn)的索引,你可以使用index(_:offsetBy:)
方法而不是多次調(diào)用這兩個(gè)方法
let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a
28.字符串的插入
- 想插入一個(gè)字符到指定的索引處乎芳,使用
insert(_:at:)
方法
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
- 想插入字符串到指定的索引處遵蚜,使用
insert(contentsOf:at:)
方法
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"
28.字符串的刪除
- 移除指定索引位置的字符,使用
remove(at:)
方法
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
- 移除指定范圍內(nèi)的字符串奈惑,使用
removeSubrange(_:)
方法
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
29.子字符串
子字符串是是一個(gè)Substring的實(shí)例吭净,不是另外一個(gè)字符串,他會復(fù)用父字符串的一部分內(nèi)存肴甸,如果你想讓這個(gè)子字符串保留的時(shí)間長一點(diǎn)寂殉,使用String方法將其轉(zhuǎn)變?yōu)樽址愋?/p>
30.集合類的不變性和可變性
和字符串一樣,集合類的可變性也是由聲明它的關(guān)鍵字是let\var
來決定的
31.數(shù)組相關(guān)
- 聲明和初始化:
完整寫法Array[ElementType]
可簡寫為[ElementType]
數(shù)組
var someInts = [Int]() //簡寫來初始化一個(gè)空數(shù)組
let intsArray = [1, 2, 3] // 用字面量語法創(chuàng)建數(shù)組 存儲的類型自動推斷為Int
- 獲取元素的數(shù)目 使用
count
屬性
let intCount = intsArray.count
- 檢查是否為空 使用
isEmpty
屬性
if intsArray.isEmpty {
print("This is an empty array")
}
- 增刪查改
someInts.append(6) // 給末尾增加一個(gè)元素
someInts += [8, 10] // 可以使用+運(yùn)算符或者+=運(yùn)算符拼接數(shù)組
someInts[0] = 0 // 使用下標(biāo)語法修改某處索引的值
someInts[1...3] = [1, 2, 3] // 使用下標(biāo)語法還可以修改一定范圍內(nèi)的值
someInts.insert(4, at:4) // 使用insert方法在指定索引處插入值
let removedInt = someInts.remove(at:5) // 使用remove語法移除指定索引處的值 該方法會返回刪除后的值
let removedInt2 = someInts.removeLast() // 移除數(shù)組末尾的值 返回刪除后的值
- 使用普通的
for-in
語法可以遍歷數(shù)組,但是如果想在遍歷的同時(shí)獲取到索引值,可以使用數(shù)組的enumerated()
方法
for (index, value) in intsArray.enumerated() {
print("Item at index \(index) is \(value)")
}
32.合集相關(guān)
- 被存入合集的元素必須是可哈希的原在,也就是必須實(shí)現(xiàn)
Hashable
協(xié)議(Hashable
協(xié)議遵循Equalable
協(xié)議)友扰,并讓其hashValue
屬性返回一個(gè)合理的Int值 - 聲明和初始化,類型聲明必須用
尖括號
而不是方括號
庶柿,數(shù)組村怪,合集,字典里只有合集沒有簡寫語法
var letters = Set<Character>() // 初始化一個(gè)存儲Character類型的空的合集
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"] // 使用字面量語法初始化 并且顯式聲明了類型信息 可以省略
- 訪問元素?cái)?shù)量使用
count
屬性 訪問是否為空使用isEmpty
屬性 和數(shù)組一樣 - 增刪查改
favoriteGenres.insert("Jazz") // 由于合集是無序的 所以直接使用insert方法來添加一個(gè)新元素
favoriteGenres.remove("Rock") // 使用remove方法來移除一個(gè)元素 被移除的元素同樣會被方法返回 可以用 removeAll()來移除合集中的所有元素
// 使用contains方法來檢查集合中是否包含了某個(gè)元素
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// sorted()方法返回一個(gè)使用 < 運(yùn)算符排序的數(shù)組
for genre in favoriteGenres.sorted() {
print("\(genre)")
}
33.字典
- 聲明和初始化 完整寫法
Dictionary<Key, Value>
浮庐,簡寫為[Key, Value]
,注意簡寫是用方括號甚负,而不是尖括號
var namesOfIntegers = [Int: String]() // 使用簡寫初始化一個(gè)空字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"] // 使用字面量語法初始化一個(gè)字典 并顯式聲明類型 可以省略
- 字典的
Key
和合集的元素一樣,必須都遵循Hashable
協(xié)議 - 訪問元素?cái)?shù)量使用
count
屬性 訪問是否為空使用isEmpty
屬性 和數(shù)組一樣 - 增刪查改 區(qū)別較大 分開說
- 下標(biāo)語法和數(shù)組不同 可以添加新元素或者更新值
airports["LHR"] = "London" // 如果`LHR`這個(gè)Key已經(jīng)存在 則更新這個(gè)值 否則添加這個(gè)值
- 使用
updateKey
方法同樣可以添加或者更新值 但是由于這個(gè)方法會返回一個(gè)可選項(xiàng)审残,當(dāng)舊值被更新時(shí)梭域,可選項(xiàng)返回舊值 因此可以用這個(gè)方法來檢查舊值是否被更新了
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was \(oldValue).")
}
- 使用下標(biāo)語法從字典的特點(diǎn)鍵中取回值,返回類型為可選項(xiàng)
if let airportName = airports["DUB"] {
print("The name of the airport is \(airportName).")
} else {
print("That airport is not in the airports dictionary.")
}
- 使用
removeValue(forKey:)
來從字典里移除鍵值對,返回值為一個(gè)可選項(xiàng)搅轿,如果刪除成功病涨,返回刪除的Value,否則返回nil
if let removedValue = airports.removeValue(forKey: "DUB") {
print("The removed airport's name is \(removedValue).")
} else {
print("The airports dictionary does not contain a value for DUB.")
}
- 使用(Key, Value)可以直接對字典進(jìn)行遍歷
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}