Swift 5.0
終於來啦, Swift 5.0
是Swift
中最備受關注的一個版本, 傳說中ABI
穩定的版本Xcode Bate 10.2
的發佈, Swift 5.0
也發佈了測試版, 相信也帶來了不少優化和改進Xcode Bate 10.2
環境中進行的@dynamicCallable
爲Swift
添加了一個新屬性, 容許使用一個簡單的語法糖調用函數同樣調用命名類型@dynamicCallable
屬性, 就必需要實現如下方法中的一個或者兩個func dynamicallyCall(withArguments args: [Int]) -> Double
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double
複製代碼
String
, Int
等等......KeyValuePairs
的使用和介紹, 沒有使用過的可參考下面看一個例子, RandomNumberGenerator
生成一個隨機數git
Swift 5.0
以前的定義和調用方式github
// 定義方式
struct RandomNumberGenerator {
func generate(numberOfZeroes: Int) -> Double {
let maximum = pow(10, Double(numberOfZeroes))
return Double.random(in: 0...maximum)
}
}
// 調用方式
let random = RandomNumberGenerator()
let num = random.generate(numberOfZeroes: 2)
print(num)
複製代碼
在
Swift 5.0
使用@dynamicCallable
屬性編程
// 定義方式
@dynamicCallable
struct RandomNumberGenerator {
func dynamicallyCall(withArguments args: [Int]) -> Double {
let numberOfZeroes = Double(args.first ?? 0)
let maximum = pow(10, numberOfZeroes)
return Double.random(in: 0...maximum)
}
}
// 調用方式
let random = RandomNumberGenerator()
let num = random(2)
// random(2)等同於random.dynamicallyCall(withArguments: [2])
print(num)
複製代碼
@dynamicCallable
使用注意事項withKeywordArguments:
而且沒有實現withArguments:
,你仍然能夠在沒有參數標籤的狀況下調用withKeywordArguments:
或withArguments:
時標記爲throw
,則調用該類型也將被拋出throw
@dynamicCallable
,只能添加到主要類型上Swift
中的每一個值都有一個特殊的僞屬性.self,它指的是整個值let id = \Int.self
var x = 1
print(id) ////Swift.WritableKeyPath<Swift.Int, Swift.Int>
x.self = 2
print(x) //2
print(x.self) //2
print(x[keyPath: id]) //2
x[keyPath: id] = 3
print(x[keyPath: id]) //3
複製代碼
在Swift 5
以前,能夠編寫一個帶有可變參數的枚舉, 可是在Swift 5
開始, 調用時會報錯, 以下swift
enum X {
// 此處定義切沒有調用時不會報錯
case foo(bar: Int...)
}
func baz() -> X {
// 此處調用時會報錯
return .foo(bar: 0, 1, 2, 3)
}
複製代碼
在Swift 5
以後, 上述定義改爲數組參數, 而不是可變參數, 以下api
enum X {
case foo(bar: [Int])
}
func baz() -> X {
return .foo(bar: [0, 1, 2, 3])
}
複製代碼
\
處理// 文字引用類型
// 錯誤寫法
let quote = "Alice: "How long is forever?" White Rabbit: "Sometimes, just one second.""
// 正確寫法
let quote1 = "Alice: \"How long is forever?\" White Rabbit: \"Sometimes, just one second.\""
// 正則表法式類型
// 錯誤寫法
let ucCaseCheck = "enum\s+.+\{.*case\s+[:upper:]"
// 正確寫法
let ucCaseCheck = "enum\\s+.+\\{.*case\\s+[:upper:]"
複製代碼
#
處理#
將字符串包裹起來#
字符串開頭和結尾的符號成爲字符串分隔符的一部分,所以以下Swift
理解「rain」
和「Spain」
周圍的獨立引號應該被視爲文字引號而不是結束字符串let rain = #"The "rain" in "Spain" falls mainly on the Spaniards."#
let keypaths = #"Swift keypaths such as \Person.name hold uninvoked references to properties."#
let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#
複製代碼
注意: 上面使用
\#(answer)
引用變量而不是\(answer)
, 由於在用#
包裹的字符串中反斜槓將會被失敗別爲文字字符而不是轉義字符, 因此必須額外的添加#
數組
##
處理#
處理, 在字符串中可使用反斜槓等特殊字符, 那若是字符串中須要使用#
, 又該如何處理??#
包裹字符串, 默認會以#
爲字符串的結束符號, #
後面的文字將再也不處理, 在這種狀況下, 咱們會使用##
處理let str = ##"My dog said "woof"#gooddog"##
複製代碼
原始字符串與Swift
的多行字符串系統徹底兼容 - 只需用於#"""
啓動,而後"""#
結束xcode
let multiline = #"""
The answer to life,
the universe,
and everything is \#(answer).
"""#
複製代碼
先看下面代碼bash
struct User {
var id: Int
init?(id: Int) {
if id < 1 {
return nil
}
self.id = id
}
func getMessages() throws -> String {
// complicated code here
return "No messages"
}
}
複製代碼
在Swift4.2
及其以前的版本中微信
let user = User(id: 1)
// 這裏獲得的message的類型是: let messages: String??
let messages = try? user?.getMessages()
// 若是咱們想獲得非可選值就須要
print((messages ?? "") ?? "")
// 或者屢次強解, 固然不建議強解寫法
print(messages!!)
複製代碼
Swift4.2
及其以前的版本中, 上面返回的是一個2層嵌套的可選值, 若是有多層嵌套處理起來也是至關更麻煩的Swift 5
中就完美的解決了這個問題, 若是當前值是可選的, 那麼try?
將不會將值包裝在可選值中, 所以最終結果只是一個String?
Swift 5
中不管有多少可嵌套的可選最後, 返回值永遠只是一個可選值as?
,你仍然只有一個級別的可選性let user = User(id: 1)
// 類型: let messages: String?
let messages = try? user?.getMessages()
print(messages ?? "")
複製代碼
isMultiple
isMultiple
let rowNumber = 4
if rowNumber.isMultiple(of: 2) {
print("Even")
} else {
print("Odd")
}
// 該方法等效於
if rowNumber % 2 == 0 {}
複製代碼
count
Swift
以前的版本中, 有一個函數filter
能夠過濾出數組中符合條件的的元素, 組成一個新的數組, 詳細使用可參考Swift函數式編程之高級用法Swift 5
中新增了一個函數count(where:)
, 能夠獲取數組中符合條件的元素的個數let arr = [1, 2, 34, 5, 6, 7, 8, 12, 45, 6, 9]
let filter = arr.filter({ $0 > 10 })
print(filter) //[34, 12, 45]
let count = arr.count(where: { $0 > 10 })
print(count) // 3
複製代碼
compactMapValues
Swift4.x
的版本有兩個函數compactMap
和mapValues
compactMap
: 返回一個操做後獲得的新的數組, 相似flatMap
mapValues
: 字典中的函數, 對字典的value
值執行操做, 返回改變value
後的新的字典let times = [
"first": 2,
"second": 43,
"three": 12,
"four": 3
]
let compact = times.compactMap({ $0.value > 10 })
print(compact)
// [true, false, true, false]
let mapValues = times.mapValues({ $0 + 2 })
print(mapValues)
// ["second": 45, "first": 4, "three": 14, "four": 5]
複製代碼
Swift 5
中新增了一個函數compactMapValues
compactMapValues
是將上述兩個方法的功能合併在一塊兒, 返回一個對value
操做後的新字典, 而且自動過濾不符合條件的鍵值對let times1 = [
"Hudson": "38",
"Clarke": "42",
"Robinson": "35",
"Hartis": "DNF"
]
let comMap2 = times1.compactMapValues({ Int($0) })
print(comMap2)
// ["Clarke": 42, "Robinson": 35, "Hudson": 38]
複製代碼
SubSequence
Sequence
協議再也不具備SubSequence
關聯類型。先前返回SubSequence
的Sequence
方法如今會返回具體類型SubSequence
的Sequence
擴展應該修改成相似地使用具體類型,或者修改成Collection
的擴展,在Collection
中SubSequence
仍然可用// swift 5不在支持
extension Sequence {
func dropTwo() -> SubSequence {
return self.dropFirst(2)
}
}
// 建議改成
extension Sequence {
func dropTwo() -> DropFirstSequence<Self> {
return self.dropFirst(2)
}
}
// 或者
extension Collection {
func dropTwo() -> SubSequence {
return self.dropFirst(2)
}
}
複製代碼
DictionaryLiteral
類型重命名爲KeyValuePairs
app
Swift 5
軟件包管理器時,Targets
能夠聲明一些經常使用的針對特定目標的build settings
設置Swift
和C
語言定義,C
語言頭文件搜索路徑,連接庫和連接框架Swift 5
時, 能夠自定義所支持的最低版本號, 若是該項目的依賴包所支持的最低版本大於項目的最低版本號, 則項目會報錯在Swift 5
中再也不支持返回Self
的類方法
// 不在支持
class Base {
class func factory() -> Self { /*...*/ }
}
複製代碼
不一樣文件中的擴展名沒法相互識別
class FirstClass { }
extension FirstClass {
class SecondClass { }
}
// 這裏將會報錯: "SecondClass is not a member type of FirstClass"
extension FirstClass.SecondClass {
class ThirdClass { }
}
複製代碼
在Swift 5
中, 在所聲明的類裏面, 所聲明的變量名不能和類名同樣
struct S {}
extension S {
static var i: Int { return 0 }
struct i {} // error: 「i」的聲明無效
}
// 下面的方式是沒有問題的
struct S1<T> {}
extension S1 {
static var i: Int { return 0 }
struct i {} // This is fine!
}
複製代碼
歡迎您掃一掃下面的微信公衆號,訂閱個人博客!