@@ -62,7 +62,7 @@ or misspelled. Guessing correctly affects not only the quality of the
6262error message, but also whether further diagnostics will be
6363useful. For example, in this code, the ` while ` keyword is misspelled:
6464
65- ``` swift
65+ ``` swift,ignore
6666func f(x: inout Int) {
6767 whilee x < 10 {
6868 x += 1
@@ -208,12 +208,14 @@ Swift supplies a function for checking that a precondition is upheld,
208208which can be used as follows:
209209
210210``` swift
211+ # let n = 0
211212precondition (n >= 0 )
212213```
213214
214215* or*
215216
216217``` swift
218+ # let n = 0
217219precondition (n >= 0 , " n == \( n ) ; it must be non-negative." )
218220```
219221
@@ -243,6 +245,8 @@ checks at function boundaries. For example, in the binary search
243245algorithm mentioned in the previous chapter,
244246
245247``` swift
248+ # var l = 0
249+ # var h = 10
246250 // precondition: l <= h
247251 let m = (h - l) / 2
248252 h = l + m
@@ -258,6 +262,8 @@ help us uncover those flaws during testing of debug builds without
258262impacting performance of release builds:
259263
260264``` swift
265+ # var l = 0
266+ # var h = 10
261267 assert (l <= h)
262268 let m = (h - l) / 2
263269 h = l + m
@@ -304,11 +310,12 @@ operations must never be turned off in release builds.
304310extension Array {
305311 /// Exchanges the first and last elements.
306312 mutating func swapFirstAndLast () {
307- precondition (! self .isEmpty )
308- if count () == 1 { return } // swapping would be a no-op.
309- withUnsafeBufferPointer { b in
310- f = b.baseAddress
311- l = f + b.count - 1
313+ precondition (! isEmpty)
314+ if count == 1 { return } // swapping would be a no-op.
315+ withUnsafeMutableBufferPointer { b in
316+ guard let base = b.baseAddress else { return }
317+ var f = base
318+ var l = base + (b.count - 1 )
312319 swap (& f.pointee , & l.pointee )
313320 }
314321 }
@@ -335,14 +342,14 @@ code in an unfinished state):
335342 /// Returns the number of unused elements when a maximal
336343 /// number of `n`-element chunks are stored in `self`.
337344 func excessWhenFilled (withChunksOfSize n : Int ) {
338- count () % n // n == 0 would violate the precondition of %
345+ count % n // n == 0 would violate the precondition of %
339346 }
340347 }
341348 ```
342349
3433502 . Something your function uses can itself report a runtime error:
344351
345- ``` swift
352+ ``` swift,ignore
346353 extension Array {
347354 /// Writes a textual representation of `self` to a temporary file
348355 /// whose location is returned.
@@ -395,11 +402,12 @@ It's appropriate to add a precondition when:
395402 we should instead propagate the error:
396403
397404 ``` swift
405+ # import Foundation
398406 extension Array {
399407 /// Writes a textual representation of `self` to a temporary file
400408 /// whose location is returned.
401409 func writeToTempFile (withChunksOfSize n : Int ) throws -> URL {
402- let r = FileManager.defaultTemporaryDirectory
410+ let r = FileManager.default . temporaryDirectory
403411 .appendingPathComponent (UUID ().uuidString )
404412 try " \( self ) " .write (to : r, atomically : false , encoding : .utf8 )
405413 return r
@@ -435,6 +443,9 @@ features to accommodate it without causing this kind of repeated
435443boilerplate:
436444
437445``` swift
446+ # func thing1ThatCanFail () -> Result<Int , Error > { .success (0 ) }
447+ # func thing2ThatCanFail () -> Result<Int , Error > { .success (0 ) }
448+ # func _resultPropagationDemo () -> Result<Int , Error > {
438449let someValueOrError = thing1ThatCanFail ()
439450guard case .success (let someValue) = someValueOrError else {
440451 return someValueOrError
@@ -444,13 +455,17 @@ let otherValueOrError = thing2ThatCanFail()
444455guard case .success (let otherValue) = otherValueOrError else {
445456 return otherValueOrError
446457}
458+ # return .success (otherValue)
459+ # }
447460```
448461
449462
450463Swift's thrown errors fill that role by propagating errors upward with
451464a simple ` try ` label on an expression containing the call.
452465
453466``` swift
467+ # func thing1ThatCanFail () throws -> Int { 0 }
468+ # func thing2ThatCanFail () throws -> Int { 0 }
454469let someValue = try thing1ThatCanFail ()
455470let otherValue = try thing2ThatCanFail ()
456471```
@@ -536,6 +551,8 @@ whose primary home is the summary sentence fragment.[^result-doc]
536551 as though they just return a ` T ` :
537552
538553 ``` swift
554+ # import Foundation
555+ # enum IOError : Error {}
539556 extension Array {
540557 /// Writes a textual representation of `self` to a temporary file,
541558 /// returning its location.
@@ -592,18 +609,19 @@ The following code uses that guarantee to ensure that all the
592609allocated buffers are eventually freed.
593610
594611```swift
612+ # struct X {}
595613/// Processes each element of `xs` in an order determined by the
596614/// [total
597615/// preorder](https://en.wikipedia.org/wiki/Weak_ordering#Total_preorders)
598616/// `areInOrder` using a distinct 1Kb buffer for each one.
599617func f (_ xs: [X], orderedBy areInOrder: (X, X) throws -> Bool ) rethrows
600618{
601619 var buffers = xs.map { x in
602- (p , UnsafeMutablePointer < UInt8 > .allocate (capacity : 1024 )) }
603- defer { for _ , b in buffers { b.deallocate () } }
620+ (x , UnsafeMutablePointer < UInt8 > .allocate (capacity : 1024 )) }
621+ defer { for ( _ , b) in buffers { b.deallocate () } }
604622
605- buffers.sort { ! areInOrder ($1 .0, $0 .0) }
606- ...
623+ try buffers.sort { ! ( try areInOrder ($1 .0, $0 .0) ) }
624+ // ...
607625}
608626```
609627
@@ -656,6 +674,7 @@ making it a precondition that the comparison is a total preorder, we
656674could weaken the postcondition as follows:
657675
658676```swift
677+ # extension Array {
659678/// Sorts the elements so that all adjacent pairs satisfy
660679/// `areInOrder`, or permutes the elements in an unspecified way if
661680/// `areInOrder` is not a [total
@@ -665,6 +684,7 @@ could weaken the postcondition as follows:
665684/// - Complexity: at most N log N comparisons, where N is the number
666685/// of elements.
667686mutating func sort (areInOrder : (Element , Element )-> Bool ) { ... }
687+ # }
668688```
669689
670690As you can see, this change makes the API more complicated to no
@@ -783,8 +803,10 @@ manage that is with a `defer` block releasing the resources
783803immediately after they are allocated:
784804
785805```swift
786- let f = try FileHandle (forReadingFrom : p)
787- defer { f.close () }
806+ # import Foundation
807+ # let p = URL (fileURLWithPath : " /tmp/example.txt" )
808+ let f: FileHandle = try .init (forReadingFrom : p)
809+ defer { try ? f.close () }
788810// use f
789811```
790812
@@ -793,15 +815,16 @@ scope where they were allocated, you can tie them to the `deinit` of
793815some type:
794816
795817```swift
818+ # import Foundation
796819struct OpenFileHandle: ~ Copyable {
797820 /// The underlying type with unmanaged close functionality
798821 private let raw: FileHandle
799822
800823 /// An instance for reading from p.
801- init (forReadingFrom p : URL) { raw = .init (forReadingFrom : p) }
824+ init (forReadingFrom p : URL) { raw = try ! .init (forReadingFrom : p) }
802825
803826 deinit {
804- raw.close ()
827+ try ? raw.close ()
805828 }
806829}
807830```
@@ -864,16 +887,20 @@ invariants. For example, imagine a disk-backed version of `PairArray`
864887from the last chapter, where I/ O operations can throw :
865888
866889```swift
890+ # struct DiskBackedArray< Element > {
891+ # init () {}
892+ # mutating func append (_ : Element ) throws {}
893+ # }
867894/// A disk-backed series of `(X, Y)` pairs, where the `X`s and `Y`s
868895/// are stored in separate files.
869896struct DiskBackedPairArray< X, Y> {
870897 // Invariant: `xs.count == ys.count`
871898
872899 /// The first part of each element.
873- private var xs = DiskBackedArray ()
900+ private var xs: DiskBackedArray<X> = DiskBackedArray ()
874901
875902 /// The second part of each element.
876- private var ys = DiskBackedArray ()
903+ private var ys: DiskBackedArray<Y> = DiskBackedArray ()
877904
878905 // ...
879906
0 commit comments