Swift函數(shù)提前返回實例詳解
簡評:
函數(shù)是一個組織在一起語句集合,以執(zhí)行特定任務(wù)。Swift 函數(shù)類似于簡單 C 函數(shù)以及復(fù)雜的 Objective C 語言函數(shù)。 它使我們能夠通過函數(shù)調(diào)用內(nèi)部的局部和全局參數(shù)值。 像其他任何語言一樣 swift 函數(shù)也遵循相同的步驟。
- 函數(shù)聲明:它告訴編譯器有關(guān)的函數(shù)的名稱,返回類型和參數(shù)。
- 函數(shù)定義:它提供函數(shù)的實際主體。
Swift 函數(shù)包含參數(shù)類型和返回類型。
函數(shù)提前返回主要的好處是:將每個錯誤處理進(jìn)行分離,審查代碼時不需要考慮多種復(fù)雜異常,我們可以吧注意力集中在也業(yè)務(wù)邏輯中,調(diào)試代碼時可以直接在異常中打斷點。
提前返回
首先來看一下需要改進(jìn)的代碼示例,我們構(gòu)建一個筆記應(yīng)用使用 NotificationCenter API,當(dāng)筆記內(nèi)容有變化時 Notification 來通知筆記列表變更,代碼如下:
class NoteListViewController: UIViewController {
@objc func handleChangeNotification(_ notification: Notification) {
let noteInfo = notification.userInfo?["note"] as? [String : Any]
if let id = noteInfo?["id"] as? Int {
if let note = database.loadNote(withID: id) {
notes[id] = note
tableView.reloadData()
}
}
}
}
上面的代碼可以很好的工作,但是可讀性差了點。因為這段代碼包含多重縮進(jìn)和類型轉(zhuǎn)換。我們來嘗試改進(jìn)這段代碼。
- 將方法提前返回,讓我們函數(shù)盡可能的快的返回。
- 使用 guard 替代 if,以避免嵌套。
class NoteListViewController: UIViewController {
@objc func handleChangeNotification(_ notification: Notification) {
let noteInfo = notification.userInfo?["note"] as? [String : Any]
guard let id = noteInfo?["id"] as? Int else {
return
}
guard let note = database.loadNote(withID: id) else {
return
}
notes[id] = note
tableView.reloadData()
}
}
將函數(shù)提前返回能夠?qū)⒐δ苁〉那闆r處理得更加清晰,這不僅提高了可讀性(更少的縮進(jìn),更少的嵌套),同時也有利于單元測試。
我們可以進(jìn)一步改進(jìn)代碼,將獲取 noteID 和類型轉(zhuǎn)換的代碼放在 Notification Extension 中,這樣就將 handleChangeNotification 業(yè)務(wù)邏輯和具體細(xì)節(jié)分離開來。修改后代碼如下所示:
private extension Notification {
var noteID: Int? {
let info = userInfo?["note"] as? [String : Any]
return info?["id"] as? Int
}
}
class NoteListViewController: UIViewController {
@objc func handleChangeNotification(_ notification: Notification) {
guard let id = notification.noteID else {
return
}
guard let note = database.loadNote(withID: id) else {
return
}
notes[id] = note
tableView.reloadData()
}
}
這種結(jié)構(gòu)還大大簡化了調(diào)試的難度,我們可以直接在每個 guard 中 return 中添加斷點來截獲所有失敗情況,而不需要單步執(zhí)行所有邏輯。
條件構(gòu)造
當(dāng)構(gòu)造一個對象實例,非常普遍的需求是需要構(gòu)建哪類對象取決于一系列的條件。
例如,啟動應(yīng)用程序時顯示哪個 view controller 取決于:
- 是否已經(jīng)登錄。
- 用戶是否已經(jīng)完成入職流程(onboarding flow)。
我們對這些條件的的實現(xiàn)可能是一系列的 if 和 else 語句,如下所示:
func showInitialViewController() {
if loginManager.isUserLoggedIn {
if tutorialManager.isOnboardingCompleted {
navigationController.viewControllers = [HomeViewController()]
} else {
navigationController.viewControllers = [OnboardingViewController()]
}
} else {
navigationController.viewControllers = [LoginViewController()]
}
}
同樣的提前返回和 guard 語句可以提升代碼可讀性,但是現(xiàn)在這種情況不是處理失敗情況,而是在不同條件下構(gòu)建不同 view controller。
現(xiàn)在來改進(jìn)這段代碼,使用輕量級的工程模式,將構(gòu)造初始界面移動到專門的函數(shù)中,該函數(shù)返回匹配條件的view controller。如下所示:
func makeInitialViewController() -> UIViewController {
guard loginManager.isUserLoggedIn else {
return LoginViewController()
}
guard tutorialManager.isOnboardingCompleted else {
return OnboardingViewController()
}
return HomeViewController()
}
func showInitialViewController() {
let viewController = makeInitialViewController()
navigationController.viewControllers = [viewController]
}
由于 makeInitialViewController 方法是個純函數(shù)(不影響外部狀態(tài),固定輸入能夠得到固定輸出),實際上影響外部狀態(tài)的只有一個地方 navigationController.viewControllers = [viewController] ,(在日常開發(fā)中狀態(tài)如果沒有得到很好的控制很容易引起 bug,所以使用更少狀態(tài)和減少對狀態(tài)的修改可以一定程度上減少 bug 出現(xiàn)的幾率)。
條件控制
最后我們來看看,函數(shù)如何簡化復(fù)雜的條件邏輯。我們來構(gòu)建一個 view controller 來顯示社交應(yīng)用的評論功能,如果滿足三個條件則運行用戶對評論進(jìn)行編輯。代碼如下:
class CommentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if comment.authorID == user.id {
if comment.replies.isEmpty {
if !comment.edited {
let editButton = UIButton()
...
view.addSubview(editButton)
}
}
}
...
}
}
這里使用了 3 個 if 嵌套邏輯,每次重新審查代碼都會比較困擾,更具之前的經(jīng)驗我們可以對代碼進(jìn)行優(yōu)化,添加 Comment extension:
extension Comment {
func canBeEdited(by user: User) -> Bool {
guard authorID == user.id else {
return false
}
guard comment.replies.isEmpty else {
return false
}
return !edited
}
}
class CommentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if comment.canBeEdited(by: user) {
let editButton = UIButton()
...
view.addSubview(editButton)
}
...
}
}
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對我們的支持。
上一篇:Swift5中從原始文本創(chuàng)建字符串的方法
欄 目:Swift
下一篇:Swift學(xué)習(xí)教程之SQLite的基礎(chǔ)使用
本文標(biāo)題:Swift函數(shù)提前返回實例詳解
本文地址:http://www.jygsgssxh.com/a1/Swift/11930.html
您可能感興趣的文章
- 01-11swift中defer幾個簡單的使用場景詳解
- 01-11Swift利用Decodable解析JSON的一個小問題詳解
- 01-11Swift中defer關(guān)鍵字推遲執(zhí)行示例詳解
- 01-11Swift中初始化init的方法小結(jié)
- 01-11Swift中定義單例的方法實例
- 01-11Swift利用純代碼實現(xiàn)時鐘效果實例代碼
- 01-11Swift中排序算法的簡單取舍詳解
- 01-11Swift如何為設(shè)置中心添加常用功能
- 01-11Swift Json實例詳細(xì)解析
- 01-11Swift利用指紋識別或面部識別為應(yīng)用添加私密保護功能


閱讀排行
本欄相關(guān)
- 01-11Swift利用Decodable解析JSON的一個小問題
- 01-11swift中defer幾個簡單的使用場景詳解
- 01-11Swift中初始化init的方法小結(jié)
- 01-11Swift中defer關(guān)鍵字推遲執(zhí)行示例詳解
- 01-11Swift利用純代碼實現(xiàn)時鐘效果實例代碼
- 01-11Swift中定義單例的方法實例
- 01-11Swift中排序算法的簡單取舍詳解
- 01-11Swift Json實例詳細(xì)解析
- 01-11Swift如何為設(shè)置中心添加常用功能
- 01-11Swift利用指紋識別或面部識別為應(yīng)用添
隨機閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實現(xiàn)頁面的局部加載
- 04-02jquery與jsp,用jquery


