【iOS印象】Swift 4.1 新特性

Binboy_王興彬發表於2019-03-04
語言特性提升
  • 條件一致性(Conditional Conformance
    • Equatable Containers:當可選型、陣列、字典等集合與容器型別中的元素遵循 Equatable 或 Hashable 協議,則其同樣遵循這些協議。包括 Codable 協議。
    • 自定義容器或集合同樣可應用泛型配置支援該特性
// Swfit 4.0

// [String] to [Int?]
let a = ["1","2","x"].map(Int.init)
a == [1,2,nil]    // 期待值應該是 ‘true’,但是~!
編譯器報錯:
//Binary operator ‘==’ cannot be applied to two ‘[Int?]’ operands.
--------------------------------------
// Swift 4.1 新增特性預設實現
extension Array: Equatable where Element: Equatable { 
    // implementation of == for Array
}

extension Optional: Equatable where Wrapped: Equatable {
    // implementation of == for Optional
}
a == [1,2,nil]                  // true
a.contains(nil)                 // true
[[1,2],[3,4],[]].index(of: [])  // 2複製程式碼
  • JSON Coder 支援駝峰命名與下劃線命名轉換
    • .keyEncodingStrategy
    • .keyDecodingStrategy
  • Equatable 和 Hashable 的一致性:
    • 對所有屬性都遵循 Equatable 或 Hashable 的 struct 和 enum 預設遵循該協議。
    • 注意!class 型別不支援這個特性
    • Comparable 協議?繼續按業務邏輯自行實現吧。
  • 協議中的關聯型別支援遞迴約束
protocol Phone {
    associatedtype Version
    associatedtype SmartPhone: Phone where SmartPhone.Version == Version, SmartPhone.SmartPhone == SmartPhone
}複製程式碼
  • 協議中使用 weak 與 unowned 修飾屬性將收到編譯警告(因為在協議中修飾其沒有意義)
class Key {}
class Pitch {}
protocol Tune {
    unowned var key: Key { get set }
    weak var pitch: Pitch? { get set }
}
class Instrument: Tune {
    var key: Key
    var pitch: Pitch?
    init(key: Key, pitch: Pitch?) {
        self.key = key        
        self.pitch = pitch
    }
}複製程式碼
  • typeOfCollection(_:) 方法中,IndexDistance 改為 Int
  • flatMap(_:) 重新命名為 compactMap(_:)
平臺配置與編譯引數更新
  • 編譯時匯入(Build Imports)
// Swift 4.0#
if os(iOS) || os(tvOS)
    import UIKit
    print("UIKit is available on this platform.")
#else    
    print("UIKit is not available on this platform.")
#endif

// Swift 4.1
#if canImport(UIKit)
    print("UIKit is available if this is printed!")
#endif複製程式碼
  • 編譯時判斷目標環境(Target Environments)
// Swift 4.0
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(tvOS) || os(watchOS))
    print("Testing in the simulator.")
#else    
    print("Testing on the device.")
#endif

// Swift 4.1
#if targetEnvironment(simulator)
    print("Testing in the simulator.")
#endif複製程式碼

相關文章