Swift4.0官方文檔學(xué)習(xí)筆記

主要記錄一下可能容易遺忘的知識點(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 這種格式

布爾值的類型為Booltruefalse這兩個(gè)常量值 和OC中的YESNO不同
可以使用let/varif來對可能為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)")
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末璧坟,一起剝皮案震驚了整個(gè)濱河市既穆,隨后出現(xiàn)的幾起案子赎懦,更是在濱河造成了極大的恐慌,老刑警劉巖循衰,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铲敛,死亡現(xiàn)場離奇詭異,居然都是意外死亡会钝,警方通過查閱死者的電腦和手機(jī)伐蒋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迁酸,“玉大人先鱼,你說我怎么就攤上這事〖轺蓿” “怎么了焙畔?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長串远。 經(jīng)常有香客問我宏多,道長,這世上最難降的妖魔是什么澡罚? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任伸但,我火速辦了婚禮,結(jié)果婚禮上留搔,老公的妹妹穿的比我還像新娘更胖。我一直安慰自己,他們只是感情好隔显,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布却妨。 她就那樣靜靜地躺著,像睡著了一般括眠。 火紅的嫁衣襯著肌膚如雪彪标。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天哺窄,我揣著相機(jī)與錄音捐下,去河邊找鬼。 笑死萌业,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奸柬。 我是一名探鬼主播生年,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼廓奕!你這毒婦竟也來了抱婉?” 一聲冷哼從身側(cè)響起档叔,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蒸绩,沒想到半個(gè)月后衙四,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡患亿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年传蹈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片步藕。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惦界,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咙冗,到底是詐尸還是另有隱情沾歪,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布雾消,位于F島的核電站灾搏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏立润。R本人自食惡果不足惜狂窑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望范删。 院中可真熱鬧蕾域,春花似錦、人聲如沸到旦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽添忘。三九已至采呐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搁骑,已是汗流浹背斧吐。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仲器,地道東北人煤率。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像乏冀,于是被迫代替她去往敵國和親蝶糯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

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