#1.添加Codable協(xié)議,方便自定義數(shù)據(jù)類型序列化
#2.添加定義多行字符串語法
#3.改進(jìn)key-value coding的keypath
#4.修改并強(qiáng)化字典功能
#5.字符串變?yōu)榧项愋?/p>
1.Swifty encoding and decoding
在Objective-C中值類型的相互影響是十分糟糕的歉糜。比如NSCoding協(xié)議一疯,類繼承它之后咒精,我們需要在類中重寫自定義的 encoding 和 decoding方法锌钮。這樣顯得十分痛苦而且很容易出錯陨闹。
在swift4.0 中,引入了新的Codable協(xié)議聘芜,可以讓你在不添加其他特殊代碼的情況下序列化和反序列化自定義的數(shù)據(jù)類型兄渺,從而不用擔(dān)心值類型的丟失。更漂亮的是汰现,你可以選擇數(shù)據(jù)被序列化為什么樣的格式:plist(XML)或者JSON挂谍。
是的,Swift 4 可以讓你在不添加任何特殊代碼的情況下將自定義數(shù)據(jù)類型序列化為JSON瞎饲。
以代碼為例:
首先口叙,我們自定義一個(gè)數(shù)據(jù)類型:
struct Language:Codable {
var name: String
var version: Int
}
let swift = Language(name:"Swift",version:4)
let php = Language(name:"PHP",version:7)
let perl = Language(name:"Perl",version:6)
讓Language這個(gè)結(jié)構(gòu)體遵從Codable協(xié)議,我們便可以將它轉(zhuǎn)化為json格式的數(shù)據(jù)展示:
let encoder = JSONEncoder()
let encoded = try? encoder.encode(swift){
//...
}
Swift將會自動編碼你的數(shù)據(jù)類型中的所有屬性嗅战。
我們可以使用encode和decode方法來編碼和解碼對象:
let encoder = JSONEncoder()
let encoded = try? encoder.encode(swift)
if encoded != nil {
if let json = String(data: encoded!,encoding:.utf8){
print(json)
}
}
let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded!)
{
print(decoded.name)
}
同樣可以有PropertyList的encode和decode:
//PropertyList
let propertyListEncoder = PropertyListEncoder()
let propertyListed = try? propertyListEncoder.encode(php)
let propertyDecoder = PropertyListDecoder()
if let value = try? propertyDecoder.decode(Language.self,from: propertyListed!)
{
print(value.name)
}
2.多行文字的字符串
之前我們可以通過使用"\n"來使字符串換行妄田。比如:
語法說明:
1.以三個(gè)雙引號作為開始的標(biāo)識。
2.以三個(gè)雙引號作為結(jié)束的標(biāo)識驮捍。
3.不管開始標(biāo)識還是結(jié)束標(biāo)識疟呐,都必須單獨(dú)占據(jù)一行
4.你定義的字符串就是開始標(biāo)識和結(jié)束標(biāo)識中間的樣子
3.改進(jìn)key-value coding的keypath
Swift中如何使用keypath呢?
首先厌漂,我們定義兩個(gè)結(jié)構(gòu)體:
struct Crew {
var name: String
var rank:String
}
struct Starship {
var name: String
var maxWarp: Double
var captain: Crew
func goToMaximumWarp(){
print("\(name) is now travelling at warp \(maxWarp)")
}
}
let janeway = Crew(name:"Kathryn Janeway",rank:"Captain")
let voyager = Starship(name: "Voyager", maxWarp: 9.975, captain: janeway)
let enterWarp = voyager.goToMaximumWarp
enterWarp()
3.改進(jìn)key-value coding的keypath
Swift中如何使用keypath呢?
首先斟珊,我們定義兩個(gè)結(jié)構(gòu)體:
struct Crew {
var name: String
var rank:String
}
struct Starship {
var name: String
var maxWarp: Double
var captain: Crew
func goToMaximumWarp(){
print("\(name) is now travelling at warp \(maxWarp)")
}
}
let janeway = Crew(name:"Kathryn Janeway",rank:"Captain")
let voyager = Starship(name: "Voyager", maxWarp: 9.975, captain: janeway)
let enterWarp = voyager.goToMaximumWarp
enterWarp()
在Swift中苇倡,我們可以給函數(shù)添加一個(gè)引用富纸。比如,我們可以給goToMaximumWarp()方法添加一個(gè)叫做enterWarp的引用旨椒,之后我們便可以使用enterWarp來調(diào)用它晓褪。然而,我們卻不能對屬性做同樣的操作综慎。是的涣仿,我們不能給Starship的name屬性添加一個(gè)引用
這個(gè)問題,可以通過使用keypath來解決:正如enterWarp()一樣示惊,它們是未被調(diào)用的屬性引用好港。 如果您現(xiàn)在調(diào)用引用,則得到當(dāng)前值米罚,但如果稍后調(diào)用引用钧汹,則獲得最新值。
keyPath的語法格式為反斜杠:
let nameKeyPath = \Starship.name
let maxWarpKeyPath = \Starship.maxWarp
let captainName = \Starship.captain.name
之后你便可以在Starship的實(shí)例中使用它了:
print(voyager[keyPath: nameKeyPath])? //Voyager
voyager[keyPath: nameKeyPath] = "456"
print(voyager.name)? //456
voyager.goToMaximumWarp()? //456 is now travelling at warp 9.975
enterWarp()? //Voyager is now travelling at warp 9.975
let starshipName = voyager[keyPath: nameKeyPath]
let starshipMaxWarp = voyager[keyPath: maxWarpKeyPath]
let starshipCaptain = voyager[keyPath: captainName]
之后你便可以在Starship的實(shí)例中使用它了:
print(voyager[keyPath: nameKeyPath])? //Voyager
voyager[keyPath: nameKeyPath] = "456"
print(voyager.name)? //456
voyager.goToMaximumWarp()? //456 is now travelling at warp 9.975
enterWarp()? //Voyager is now travelling at warp 9.975
let starshipName = voyager[keyPath: nameKeyPath]
let starshipMaxWarp = voyager[keyPath: maxWarpKeyPath]
let starshipCaptain = voyager[keyPath: captainName]
4.改進(jìn)了字典功能:
Swift4.0 讓Dictionary的功能更強(qiáng)大录择。
在Swift3.0 中拔莱,Dictionary的filter函數(shù)會返回一個(gè)包含key/value元組的數(shù)組。
比如
let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000];
let massiveCities = cities.filter { $0.value > 10_000_000 }
在Swift3.0中隘竭,你不能通過massiveCities["Shanghai"]來獲取對應(yīng)的值塘秦。因?yàn)閙assiveCities不是一個(gè)字典類型。只能通過massiveCities[0].value來獲取动看。
但在Swift4.0中尊剔,massiveCities是字典類型,使用massiveCities["Shanghai"]獲取值完全沒有問題弧圆。
print(massiveCities["Shanghai"] ?? "nil Value");
5.String 又變成了集合類型:
這意味著赋兵,你可以做字符串倒置,循環(huán)獲取每個(gè)字符搔预,map()霹期,flatMap()等操作。
let quote = "It is a truth universally acknowledged that new Swift versions bring new features."
let reversed = quote.reversed()
for letter in quote {
print(letter)
}
另外拯田,Swift4.0 中历造,引入類似于python中字符串的一些操作。在省略起始位置或者結(jié)束位置的情況下船庇,可以自動推斷集合的起始位置或者結(jié)束位置吭产。
let characters = ["Dr Horrible", "Captain Hammer", "Penny", "Bad Horse", "Moist"]
let bigParts = characters[..<3]
let smallParts = characters[3...]
print(bigParts)? ? //["Dr Horrible", "Captain Hammer", "Penny"]
print(smallParts)? //["Bad Horse", "Moist"]