swift4.0的新特性

#1.添加Codable协议,方便自定义数据类型序列化

#2.添加定义多行字符串语法

#3.改进key-value coding的keypath

#4.修改并强化字典功能

#5.字符串变为集合类型

1.Swifty encoding and decoding

在Objective-C中值类型的相互影响是十分糟糕的。比如NSCoding协议,类继承它之后,我们需要在类中重写自定义的 encoding 和 decoding方法。这样显得十分痛苦而且很容易出错。

在swift4.0 中,引入了新的Codable协议,可以让你在不添加其他特殊代码的情况下序列化和反序列化自定义的数据类型,从而不用担心值类型的丢失。更漂亮的是,你可以选择数据被序列化为什么样的格式:plist(XML)或者JSON。

是的,Swift 4 可以让你在不添加任何特殊代码的情况下将自定义数据类型序列化为JSON。

以代码为例:

首先,我们自定义一个数据类型:

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这个结构体遵从Codable协议,我们便可以将它转化为json格式的数据展示:

let encoder = JSONEncoder()

let encoded = try? encoder.encode(swift){

//...

}

Swift将会自动编码你的数据类型中的所有属性。

我们可以使用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.以三个双引号作为开始的标识。

2.以三个双引号作为结束的标识。

3.不管开始标识还是结束标识,都必须单独占据一行

4.你定义的字符串就是开始标识和结束标识中间的样子

3.改进key-value coding的keypath

Swift中如何使用keypath呢?

首先,我们定义两个结构体:

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.改进key-value coding的keypath

Swift中如何使用keypath呢?

首先,我们定义两个结构体:

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中,我们可以给函数添加一个引用。比如,我们可以给goToMaximumWarp()方法添加一个叫做enterWarp的引用,之后我们便可以使用enterWarp来调用它。然而,我们却不能对属性做同样的操作。是的,我们不能给Starship的name属性添加一个引用

这个问题,可以通过使用keypath来解决:正如enterWarp()一样,它们是未被调用的属性引用。 如果您现在调用引用,则得到当前值,但如果稍后调用引用,则获得最新值。

keyPath的语法格式为反斜杠:

let nameKeyPath = \Starship.name

let maxWarpKeyPath = \Starship.maxWarp

let captainName = \Starship.captain.name

之后你便可以在Starship的实例中使用它了:

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的实例中使用它了:

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.改进了字典功能:

Swift4.0 让Dictionary的功能更强大。

在Swift3.0 中,Dictionary的filter函数会返回一个包含key/value元组的数组。

比如

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"]来获取对应的值。因为massiveCities不是一个字典类型。只能通过massiveCities[0].value来获取。

但在Swift4.0中,massiveCities是字典类型,使用massiveCities["Shanghai"]获取值完全没有问题。

print(massiveCities["Shanghai"] ?? "nil Value");

5.String 又变成了集合类型:

这意味着,你可以做字符串倒置,循环获取每个字符,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中字符串的一些操作。在省略起始位置或者结束位置的情况下,可以自动推断集合的起始位置或者结束位置。

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"]

你可能感兴趣的:(swift4.0的新特性)