Swift---協議和擴充套件、 錯誤處理、泛型

weixin_33728268發表於2018-12-02

 使用協議宣告協議。

     protocol ExampleProtocol {

     var simpleDescription: String { get }

     mutating func adjust()

     }


     類、列舉和結構都可以採用協議。

     class SimpleClass: ExampleProtocol {

     var simpleDescription: String = "A very simple class."

     var anotherProperty: Int = 69105

     func adjust() {

     simpleDescription += "  Now 100% adjusted."

     }

     }

     var a = SimpleClass()

     a.adjust()

     let aDescription = a.simpleDescription


     struct SimpleStructure: ExampleProtocol {

     var simpleDescription: String = "A simple structure"

     mutating func adjust() {

     simpleDescription += " (adjusted)"

     }

     }

     var b = SimpleStructure()

     b.adjust()

     let bDescription = b.simpleDescription


     注意在SimpleStructure宣告中使用mutation關鍵字來標記修改結構的方法。SimpleClass的宣告不需要任何標記為mutation的方法,因為類上的方法總是可以修改類。


     使用擴充套件向現有型別新增功能,例如新方法和計算屬性。您可以使用擴充套件將協議一致性新增到其他地方宣告的型別,甚至新增到從庫或框架匯入的型別。


     extension Int: ExampleProtocol {

     var simpleDescription: String {

     return "The number \(self)"

     }

     mutating func adjust() {

     self += 42

     }

     }

     print(7.simpleDescription)

     // Prints "The number 7"



     您可以像使用任何其他命名型別一樣使用協議名稱—例如,建立具有不同型別但都符合單個協議的物件集合。當您處理型別為協議型別的值時,協議定義之外的方法不可用。


     let protocolValue: ExampleProtocol = a

     print(protocolValue.simpleDescription)

     // Prints "A very simple class.  Now 100% adjusted."

     // print(protocolValue.anotherProperty)  // Uncomment to see the error


使用採用錯誤協議的任何型別表示錯誤。

     enum PrinterError: Error {

     case outOfPaper

     case noToner

     case onFire

     }


     有幾種方法可以處理錯誤。一種方法是使用do-catch。在do塊中,您可以通過在前面寫入try來標記可能丟擲錯誤的程式碼。在catch塊中,除非您給它一個不同的名稱,否則錯誤將自動被指定為名稱錯誤。


     do {

     let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")

     print(printerResponse)

     } catch {

     print(error)

     }

     // Prints "Job sent"


     另一種處理錯誤的方法是使用try?將結果轉換為可選的。如果函式丟擲一個錯誤,特定的錯誤將被丟棄,結果為nil。否則,結果是一個可選的,包含函式返回的值。

     let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")

     let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")



泛型


     在尖括號內寫一個名稱來建立泛型函式或型別。

     func makeArray(repeating item: Item, numberOfTimes: Int) -> [Item] {

     var result = [Item]()

     for _ in 0..

     result.append(item)

     }

     return result

     }


     print( makeArray(repeating: "knock", numberOfTimes: 4))

     //["knock", "knock", "knock", "knock"]


     您可以建立函式和方法的通用 泛型形式,以及類、列舉和結構的。

     enum OptionalValue {

     case none

     case some(Wrapped)

     }

     var possibleInteger: OptionalValue = .none

     print(possibleInteger)

     // none


     possibleInteger = .some(100)

     print(possibleInteger)

     // some(100)



     在正文前面指定需求列表——例如,要求型別實現協議,要求兩種型別相同,或者要求類具有特定的超類。


     func anyCommonElements(_ lhs: T, _ rhs: U) -> Bool

     where T.Element: Equatable, T.Element == U.Element

     {

     for lhsItem in lhs {

     for rhsItem in rhs {

     if lhsItem == rhsItem {

     return true

     }

     }

     }

     return false

     }


     print(anyCommonElements([1, 2, 3], [3]))

     // true

相關文章