新特性列表
1 序列化與反序列化
2 String的多行存儲
3 key-value Coding的優(yōu)化
4 Range單邊界特性
5 Dictionary功能的優(yōu)化
6 String是一個集合
序列化與反序列化
Swift4中新添加了Codable協(xié)議讓你可以非常方便的對值類型進行序列化以及反序列化,而不用擔(dān)心丟失。
方便對于數(shù)據(jù)類型和JSON進行相互轉(zhuǎn)化。
過去進行序列化,對于一個類/結(jié)構(gòu)體中的屬性,通常需要一條一條進行轉(zhuǎn)化,然后進入Swift4之后,可以省去這些繁瑣的步驟。
var data: Data?
struct Student: Codable {
var name: String
var age: Int
}
let student1 = Student.init(name: "小明", age: 5)
let student2 = Student.init(name: "ericwang", age: 19)
let student3 = Student.init(name: "zhang", age: 8)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(student1) {
//此時encoded為data類型
//對于類型內(nèi)部的屬性,swift會自動進行序列化,不需要額外的做事。
}
let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Student.self, from: data!) {
//此時decoded為 Student類型。
print(decoded.name)
}
更多的細節(jié)部分我會開一個新章節(jié)講。
String的多行存儲
我是很喜歡這個特性
過去在Swift中,如果需要在字符串中進行換行,需要手動敲入\n來進行換行。這讓人讀起來非常的不方便。但至少來說,它滿足了用戶換行的需求。
但是一直希望有類似于所見即所得這樣的極致——怎么敲進去的,就怎么顯示出來。Swift4滿足了我這個需求。
使用"""三個雙引號進行字符串的標(biāo)識
"""
I am very glad!
Thank you!
I love you !
"""

上面的代碼會生成一個新的字符串,并在規(guī)定出添加換行符,非常便于用戶讀寫。
需要注意的是:內(nèi)容不能與"""處于同一行,前后均是。
key-value Coding優(yōu)化
Objective-C語言中非常棒的一個特性就是可以動態(tài)的索引一個屬性。這主要是由于keypaths,并不是直接訪問數(shù)據(jù)——因為這并未直接進行讀寫,而是暫時性的存儲以待后續(xù)使用。
如果以前沒有使用過keypaths,我將舉例說明。
struct Son {
var name: String
var age: Int
}
struct Father {
var name: String
var age: Int
var son: Son
func getSon() {
print("\(name) is \(son.name)'s father")
}
}
let xiaoming = Son.init(name: "xiaoming", age: 5)
let laowang = Father.init(name: "laowang", age: 38, son: xiaoming)
let getSon = laowang.getSon // ()->()
getSon() // laowang is xiaoming's father
小科普
類型:規(guī)定了變量可以取的值得范圍,以及該類型的值可以進行的操作
根據(jù)類型的值可以賦值的情況,可以把類型分為三類:
1.一級的(first class) 該等級的類型的值可以傳給子程序作為參數(shù)、可以從子程序返回、可以賦值給變量。大多數(shù)程序設(shè)計語言里,整型、字符類型等簡單類型都是一級的。
2.二級的(second class) 該等級類型的值可以傳遞給子程序作為參數(shù),但是不能從子程序里返回,也不能賦值給變量。
3.三級的(third class) 該等級類型的值聯(lián)作為參數(shù)傳遞也不行。
關(guān)于類型的詳細分析
好,回到正題,swift中function就是一個first class。上方代碼塊中let getSon = laowang.getSon就是建立一個對getSon()方法的索引。后續(xù)我們可以隨時進行訪問。
但是,我們不能對一個具體的屬性建立這樣的索引。例如let name = laowang.name,因為這相當(dāng)與值類型的賦值,而非索引。
使用keypaths可以解決上述的痛點。類似于let getSon = laowang.getSon,如果拿到了索引就能獲取當(dāng)前的值,并且swift使用類型推斷來保證你獲取的是正確的類型。
keypaths樣式如下圖所示,使用符號\作為起始,后面也可以獲得代碼提示,相較于過去的字符串形式更加的安全。

let sonNameKeypath = \Son.name
let sonAgeKeypath = \Son.age
let name = xiaoming[keyPath: sonNameKeypath]
// 結(jié)果是 獲得字符串 “xiaoming”
//keypath也可以進行連接 比如:
let fatherSonKeypath = \Father.son
let finalPath = fatherSonKeypath.appending(path: \.name)
laowang[keyPath: finalPath]
//結(jié)果是獲取字符串 “小明“
Range單邊界特性
舉個例子
let array = ["1","2","3","4","5"]
let array1 = array[1...3] //["2", "3", "4"]
let array2 = array[...3] //["1", "2", "3", "4"]
let array3 = array[1...] // ["2", "3", "4", "5"]
let array4 = array[..<4] // ["1", "2", "3", "4"]
在swift4之前的版本中,我們主要使用Range的兩個符號..., ..<分別表示一個區(qū)間的雙閉區(qū)間和前開后閉區(qū)間。
但是在Swift4中加入了新的特性。在...和..<兩個符號左側(cè)空置時,表示左側(cè)從起始點開始,如array2和array4。而對應(yīng)的在右側(cè)空置時,表示右側(cè)終結(jié)點為整個序列的末尾,如array3。這在很大程度上也方便了開發(fā)者,尤其是對于String類型的Range進行操作時。
Dictionary功能的優(yōu)化
Swift4中的字典型變得更加強大。
filter操作
在早起的Swift3中,對于一個Dictionary進行filter操作,返回的并不是一個Dictionary,而是一個元素為元組的Array。如下圖示例,返回的類型為[(key: String, value: Int)]

這里你并不能使用
p["a"],因為p并不是一個字典型。正確的調(diào)用方法是p[0].value但是在Swift4之后,對這個問題進行了修正。返回的結(jié)果變?yōu)?code>["d": 4, "c": 3]
map與mapValues操作
此外,字典型的map函數(shù)返回的仍然為array類型,但是添加了一個新的方法mapValues,滿足了整個字典進行轉(zhuǎn)換的需要

let dict = ["a":1,"b":2,"c":3,"d":4]
let a = dict.mapValues { value -> Int in
return value * 2
}
//a的輸出為 ["b": 4, "a": 2, "d": 8, "c": 6]
Dictionary.init(grouping: , by: )
看到一個很有意思的特性,把Array的元素通過一定的邏輯進行分類,形成字典型。 看下面例子。
let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000,
"Beijing": 21_516_000, "Seoul": 9_995_000];
let groupedCities = Dictionary(grouping: cities.keys)
{ $0.characters.first! }
print(groupedCities)
//輸出結(jié)果 ["B": ["Beijing"], "S": ["Shanghai", "Seoul"], "K":["Karachi"]]
ToBeContinue
String重新變?yōu)榧?/h2>
Swift4中String類型又重新變?yōu)橐粋€集合,這也就以為著,可以進行的操作又變多了:翻轉(zhuǎn)、輪尋、‘map’、‘flatmap’等遍歷操作。