swiftiOS Developer

Swift4新特性

2017-06-08  本文已影响1499人  Dreamer_做梦的人

新特性列表
1 序列化与反序列化
2 String的多行存储
3 key-value Coding的优化
4 Range单边界特性
5 Dictionary功能的优化
6 String是一个集合

序列化与反序列化

Swift4中新添加了Codable协议让你可以非常方便的对值类型进行序列化以及反序列化,而不用担心丢失。
方便对于数据类型和JSON进行相互转化。
过去进行序列化,对于一个类/结构体中的属性,通常需要一条一条进行转化,然后进入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类型
    //对于类型内部的属性,swift会自动进行序列化,不需要额外的做事。
  
}

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Student.self, from: data!) {
  //此时decoded为 Student类型。
    print(decoded.name)
}

更多的细节部分我会开一个新章节讲。

String的多行存储

我是很喜欢这个特性
过去在Swift中,如果需要在字符串中进行换行,需要手动敲入\n来进行换行。这让人读起来非常的不方便。但至少来说,它满足了用户换行的需求。
但是一直希望有类似于所见即所得这样的极致——怎么敲进去的,就怎么显示出来。Swift4满足了我这个需求。
使用"""三个双引号进行字符串的标识

""" 
    I am very glad!
    Thank you!
    I love you !
"""
playground实测

上面的代码会生成一个新的字符串,并在规定出添加换行符,非常便于用户读写。
需要注意的是:内容不能与"""处于同一行,前后均是。

key-value Coding优化

Objective-C语言中非常棒的一个特性就是可以动态的索引一个属性。这主要是由于keypaths,并不是直接访问数据——因为这并未直接进行读写,而是暂时性的存储以待后续使用。
如果以前没有使用过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


小科普

类型:规定了变量可以取的值得范围,以及该类型的值可以进行的操作
根据类型的值可以赋值的情况,可以把类型分为三类:
1.一级的(first class) 该等级的类型的值可以传给子程序作为参数、可以从子程序返回、可以赋值给变量。大多数程序设计语言里,整型、字符类型等简单类型都是一级的。
2.二级的(second class) 该等级类型的值可以传递给子程序作为参数,但是不能从子程序里返回,也不能赋值给变量。
3.三级的(third class) 该等级类型的值联作为参数传递也不行。
关于类型的详细分析

好,回到正题,swift中function就是一个first class。上方代码块中let getSon = laowang.getSon就是建立一个对getSon()方法的索引。后续我们可以随时进行访问。
但是,我们不能对一个具体的属性建立这样的索引。例如let name = laowang.name,因为这相当与值类型的赋值,而非索引。
使用keypaths可以解决上述的痛点。类似于let getSon = laowang.getSon,如果拿到了索引就能获取当前的值,并且swift使用类型推断来保证你获取的是正确的类型。
keypaths样式如下图所示,使用符号\作为起始,后面也可以获得代码提示,相较于过去的字符串形式更加的安全。

keypaths样式
let sonNameKeypath = \Son.name
let sonAgeKeypath = \Son.age
let name = xiaoming[keyPath: sonNameKeypath]
// 结果是 获得字符串 “xiaoming”

//keypath也可以进行连接 比如:
let fatherSonKeypath = \Father.son
let finalPath = fatherSonKeypath.appending(path: \.name)
laowang[keyPath: finalPath]


//结果是获取字符串 “小明“

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的两个符号..., ..<分别表示一个区间的双闭区间和前开后闭区间。
但是在Swift4中加入了新的特性。在.....<两个符号左侧空置时,表示左侧从起始点开始,如array2和array4。而对应的在右侧空置时,表示右侧终结点为整个序列的末尾,如array3。这在很大程度上也方便了开发者,尤其是对于String类型的Range进行操作时。

Dictionary功能的优化

Swift4中的字典型变得更加强大。
filter操作
在早起的Swift3中,对于一个Dictionary进行filter操作,返回的并不是一个Dictionary,而是一个元素为元组的Array。如下图示例,返回的类型为[(key: String, value: Int)]

例子
这里你并不能使用p["a"],因为p并不是一个字典型。正确的调用方法是p[0].value
但是在Swift4之后,对这个问题进行了修正。返回的结果变为["d": 4, "c": 3]

map与mapValues操作
此外,字典型的map函数返回的仍然为array类型,但是添加了一个新的方法mapValues,满足了整个字典进行转换的需要

Snip20170608_11.png
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)

 //输出结果    ["B": ["Beijing"], "S": ["Shanghai", "Seoul"], "K":["Karachi"]]

ToBeContinue

String重新变为集合

Swift4中String类型又重新变为一个集合,这也就以为着,可以进行的操作又变多了:翻转轮寻、‘map’、‘flatmap’等遍历操作。

上一篇下一篇

猜你喜欢

热点阅读