Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.64 KB | None | 0 0
  1. //
  2. // Swift 3
  3. //
  4.  
  5. /*
  6. 1. Defining
  7. 2. Throwing
  8. 1. Can use `guard`
  9. 2. Initializers
  10. 3. Catching 
  11. 4. Propagating 
  12. 1. Method throwing error should terminate signature with `throws`
  13. 5. Converting
  14. 1. Use `try?` to handle an error by converting it to an optional value
  15. 6. Disabling
  16. 1. Use `try!`
  17. 7. Clean up with `defer`
  18. */
  19.  
  20. struct Item {
  21. var price: Int
  22. var count: Int
  23. }
  24.  
  25. // 1) Defining
  26. // In Swift, errors are represented by values of types that conform to the Error protocol
  27. enum VendingMachineError: Error {
  28. case outOfStock
  29. case insufficientFunds(coinsNeeded: Int)
  30. }
  31.  
  32. class VendingMachine {
  33.  
  34. var inventory = [
  35. "Candy Bar": Item(price: 12, count: 7),
  36. "Chips": Item(price: 10, count: 4),
  37. "Pretzels": Item(price: 7, count: 11)
  38. ]
  39. var coinsDeposited = 0
  40.  
  41. /*
  42. To indicate that a function, method, or initializer can throw an error, 
  43. you write the throws keyword in the functions declaration after its parameters.
  44. A function marked with throws is called a throwing function.
  45. Any code that calls this method must either handle the errors using 
  46. 1/ a do-catch statement, 2/ try?, or 3/ try! or continue to propagate them
  47. */
  48. func vend(itemNamed name: String) throws { // 4.1) terminate signature with 'throws'
  49.  
  50. // 2.1) Use 'guard' statements to exit the method early and throw appropriate errors 
  51. // if any of the requirements for purchasing a snack aren't met
  52. guard item.count > 0 else {
  53. throw VendingMachineError.outOfStock // 2) Throwing
  54. }
  55. guard item.price <= coinsDeposited else {
  56. throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited) // 2) Throwing
  57. }
  58.  
  59. coinsDeposited -= item.price
  60.  
  61. var newItem = item
  62. newItem.count -= 1
  63. inventory[name] = newItem
  64.  
  65. print("Dispensing \(name)")
  66. }
  67. }
  68.  
  69. let favoriteSnacks = [ "Alice": "Chips", "Bob": "Licorice", "Eve": "Pretzels", ]
  70.  
  71. // 4.1) Propagating
  72. // Prefix call function throwing an Error with the `try` keyword
  73. func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
  74.  
  75. // The nil-coalescing operator (a ?? b) unwraps an optional a if it contains a value, 
  76. // or returns a default value b if a is nil
  77. let snackName = favoriteSnacks[person] ?? "Candy Bar"
  78.  
  79. try vendingMachine.vend(itemNamed: snackName)
  80. }
  81.  
  82. // 2.2) Throwing initializers can propagate errors in the same way as throwing functions
  83. struct PurchasedSnack {
  84. let name: String
  85.  
  86. init(name: String, vendingMachine: VendingMachine) throws { // 2.2) Throwing initializers 
  87. try vendingMachine.vend(itemNamed: name)
  88. self.name = name
  89. }
  90. }
  91.  
  92. var vendingMachine = VendingMachine()
  93. vendingMachine.coinsDeposited = 8
  94.  
  95. // 3) Catching
  96. do {
  97. try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
  98. } catch VendingMachineError.outOfStock {
  99. print("Out of Stock.")
  100. } catch VendingMachineError.insufficientFunds(let coinsNeeded) {
  101. print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
  102. }
  103. // Prints "Insufficient funds. Please insert an additional 2 coins."
  104.  
  105.  
  106. //
  107. // 5) Converting Errors to Optional Values
  108. //
  109.  
  110. func someThrowingFunction() throws -> Int {
  111. // ...
  112. }
  113.  
  114. // You use 'try?' to handle an error by converting it to an optional value. 
  115. // If an error is thrown while evaluating the try? expression, the value of the expression is nil.
  116. let x = try? someThrowingFunction()
  117.  
  118. // It is equivalent to:
  119. let y: Int?
  120. do {
  121. y = try someThrowingFunction()
  122. } catch {
  123. y = nil
  124. }
  125.  
  126. func fetchData() -> Data? {
  127. if let data = try? fetchDataFromDisk() { return data }
  128. if let data = try? fetchDataFromServer() { return data }
  129. return nil
  130. }
  131.  
  132.  
  133. //
  134. // 6) Disabling Error Propagation
  135. //
  136. // Sometimes you know a throwing function or method won't, in fact, throw an error at runtime.
  137. // If an error actually is thrown, you'll get a runtime error.
  138. let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
  139.  
  140.  
  141.  
  142. //
  143. // 7) Specifying Cleanup Actions
  144. //
  145. func processFile(filename: String) throws {
  146. if exists(filename) {
  147. let file = open(filename)
  148.  
  149. // Use a 'defer' statement to execute a set of statements 
  150. // just before code execution leaves the current block of code.
  151. // Deferred actions are executed in reverse order of how they are specified that is, 
  152. // the code in the first defer statement executes after code in the second, and so on.
  153. defer {
  154. close(file)
  155. }
  156. while let line = try file.readline() {
  157. // Work with the file.
  158. }
  159. // close(file) is called here, at the end of the scope.
  160. }
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement