[swift 進階]讀書筆記-第八章:錯誤處理 C8P6 defer語法可以讓程式碼更簡潔 Clearing Up Using

liaoWorking在掘金發表於2019-03-28

錯誤處理 Error Handling

8.6 defer語法可以讓程式碼更簡潔 Clearing Up Using defer

本小節內容比較簡單,主要延續之前的檔案的有效性查詢的Demo來引出defer語法,並介紹一些相關特性

引出defer關鍵字: 一般在可能丟擲異常的方法都會使用 try/finally結構。無論最後是否有丟擲異常都會走finally流程。 這個時候我們就可以使用defer語法讓程式碼變得更靈活

defer關鍵字的作用:實際是一個閉包,在當前宣告的作用域結束時執行

defer在檔案讀寫中的使用.

func contents(ofFile ?lename: String) throws -> String {
	 let file = open("test.txt", O_RDONLY)
	 defer { close(file) }
	 let contents = try process(file: file) 
	 return contents 
}
複製程式碼
注1:在上面的demo中,如果不用defer關鍵字 當出現異常,直接就try 提前結束了. 導致當前的檔案流沒有執行close方法。這個在以後的資料庫操作中可算是一個重大bug
注2: defer要寫在reture 前面。 雖然它的執行上在return後。 你寫在return後面,程式碼編譯 return後的程式碼看都不看。這個時候你寫defer實際上沒啥用。

標準庫中對defer的使用

下面會寫出```Enumeratedlterator```協議中```next()```方法的程式碼實現。
##### 使用場景:增加計數器的值而且需要返回沒有增加值之前的值。

	struct EnumeratedIterator<Base: IteratorProtocol>: IteratorProtocol, Sequence { 
		internal var _base: Base 
		internal var _count: Int ...
		func next() -> Element? { 
			guard let b = _base.next() else { return nil } 
			defer { _count += 1 } 
			return (offset: _count, element: b) 
		} 
	}
複製程式碼

多defer方法多使用注意

寫一個運算元據庫的Demo來講講
	guard let database = openDatabase(...) else { return } 
	defer { closeDatabase(database) } 
	guard let connection = openConnection(database) else { return } 
	defer { closeConnection(connection) } 
	guard let result = runQuery(connection, ...) else { return }
複製程式碼

類似於壓棧操作,前面的後執行,後面的先執行。

上面的demo中的順序也是在執行完資料庫查詢之後先```關閉連結```,再去```關閉資料庫```。
複製程式碼

over~

文章原始檔地址,大家如果有更好的想法和觀點歡迎交流

相關文章