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)
}

了解更多關于swift4.0 encode和decode的內容,可以參考鏈接:the Swift Evolution proposal for this new feature

2.多行文字的字符串:

之前我們可以通過使用"\n"來使字符串換行。比如:

let beforeString = "When you write a string that spans multiple \nlines make sure you start its content on a  \nline all of its own, and end it with three \nquotes also on a line of their own. Multi-line strings also let you write \"quote marks\" \nfreely inside your strings, which is great!"
//print(beforeString)

這種方式閱讀起來很不方便,看起來很不美觀,不能直觀的顯示它所要呈現給用戶展示的樣子。
在swift4.0中,提供了專門的語法來顯示多行字符串,從而告別轉義。

let longString = """
When you write a string that spans multiple
lines make sure you start its content on a
line all of its own, and end it with three
quotes also on a line of their own.
Multi-line strings also let you write "quote marks"
freely inside your strings, which is great!
"""
print(longString)

語法說明:
1.以三個雙引號作為開始的標識。
2.以三個雙引號作為結束的標識。
3.不管開始標識還是結束標識,都必須單獨占據一行
4.你定義的字符串就是開始標識和結束標識中間的樣子

了解更多可以參考鏈接:the Swift Evolution proposal for this new feature.

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

想要了解更多,可以參考鏈接:the Swift Evolution proposal for this new feature

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");

想要了解更多,可以參考鏈接:the Swift Evolution proposal for these new features.

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

想要了解更多,可以參考鏈接:the Swift Evolution proposal for this new feature.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容