麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > Swift > 正文

Swift函數(shù)提前返回實(shí)例詳解

2020-03-09 17:31:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

簡(jiǎn)評(píng):

函數(shù)是一個(gè)組織在一起語(yǔ)句集合,以執(zhí)行特定任務(wù)。Swift 函數(shù)類似于簡(jiǎn)單 C 函數(shù)以及復(fù)雜的 Objective C 語(yǔ)言函數(shù)。 它使我們能夠通過(guò)函數(shù)調(diào)用內(nèi)部的局部和全局參數(shù)值。 像其他任何語(yǔ)言一樣 swift 函數(shù)也遵循相同的步驟。

  • 函數(shù)聲明:它告訴編譯器有關(guān)的函數(shù)的名稱,返回類型和參數(shù)。
  • 函數(shù)定義:它提供函數(shù)的實(shí)際主體。

Swift 函數(shù)包含參數(shù)類型和返回類型。

函數(shù)提前返回主要的好處是:將每個(gè)錯(cuò)誤處理進(jìn)行分離,審查代碼時(shí)不需要考慮多種復(fù)雜異常,我們可以吧注意力集中在也業(yè)務(wù)邏輯中,調(diào)試代碼時(shí)可以直接在異常中打斷點(diǎn)。

提前返回

首先來(lái)看一下需要改進(jìn)的代碼示例,我們構(gòu)建一個(gè)筆記應(yīng)用使用 NotificationCenter API,當(dāng)筆記內(nèi)容有變化時(shí) Notification 來(lái)通知筆記列表變更,代碼如下:

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] = notetableView.reloadData()}}}}

上面的代碼可以很好的工作,但是可讀性差了點(diǎn)。因?yàn)檫@段代碼包含多重縮進(jìn)和類型轉(zhuǎn)換。我們來(lái)嘗試改進(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] = notetableView.reloadData()}}

將函數(shù)提前返回能夠?qū)⒐δ苁〉那闆r處理得更加清晰,這不僅提高了可讀性(更少的縮進(jìn),更少的嵌套),同時(shí)也有利于單元測(cè)試。

我們可以進(jìn)一步改進(jìn)代碼,將獲取 noteID 和類型轉(zhuǎn)換的代碼放在 Notification Extension 中,這樣就將 handleChangeNotification 業(yè)務(wù)邏輯和具體細(xì)節(jié)分離開(kāi)來(lái)。修改后代碼如下所示:

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] = notetableView.reloadData()}}

這種結(jié)構(gòu)還大大簡(jiǎn)化了調(diào)試的難度,我們可以直接在每個(gè) guard 中 return 中添加斷點(diǎn)來(lái)截獲所有失敗情況,而不需要單步執(zhí)行所有邏輯。

條件構(gòu)造

當(dāng)構(gòu)造一個(gè)對(duì)象實(shí)例,非常普遍的需求是需要構(gòu)建哪類對(duì)象取決于一系列的條件。

例如,啟動(dòng)應(yīng)用程序時(shí)顯示哪個(gè) view controller 取決于:

  • 是否已經(jīng)登錄。
  • 用戶是否已經(jīng)完成入職流程(onboarding flow)。

我們對(duì)這些條件的的實(shí)現(xiàn)可能是一系列的 if 和 else 語(yǔ)句,如下所示:

func showInitialViewController() {if loginManager.isUserLoggedIn {if tutorialManager.isOnboardingCompleted {navigationController.viewControllers = [HomeViewController()]} else {navigationController.viewControllers = [OnboardingViewController()]}} else {navigationController.viewControllers = [LoginViewController()]}}

同樣的提前返回和 guard 語(yǔ)句可以提升代碼可讀性,但是現(xiàn)在這種情況不是處理失敗情況,而是在不同條件下構(gòu)建不同 view controller。

現(xiàn)在來(lái)改進(jìn)這段代碼,使用輕量級(jí)的工程模式,將構(gòu)造初始界面移動(dòng)到專門(mén)的函數(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 方法是個(gè)純函數(shù)(不影響外部狀態(tài),固定輸入能夠得到固定輸出),實(shí)際上影響外部狀態(tài)的只有一個(gè)地方 navigationController.viewControllers = [viewController] ,(在日常開(kāi)發(fā)中狀態(tài)如果沒(méi)有得到很好的控制很容易引起 bug,所以使用更少狀態(tài)和減少對(duì)狀態(tài)的修改可以一定程度上減少 bug 出現(xiàn)的幾率)。

條件控制

最后我們來(lái)看看,函數(shù)如何簡(jiǎn)化復(fù)雜的條件邏輯。我們來(lái)構(gòu)建一個(gè) view controller 來(lái)顯示社交應(yīng)用的評(píng)論功能,如果滿足三個(gè)條件則運(yùn)行用戶對(duì)評(pí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 個(gè) if 嵌套邏輯,每次重新審查代碼都會(huì)比較困擾,更具之前的經(jīng)驗(yàn)我們可以對(duì)代碼進(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é)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)VEVB武林網(wǎng)的支持。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到swift教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 草操视频 | 亚洲成a| 欧美成人黄色 | 午夜啪视频 | 毛片在线视频观看 | 亚洲特黄妇女高潮 | 看免费av| 精品国产欧美一区二区 | 国产88久久久国产精品免费二区 | 欧美成人午夜一区二区三区 | 92自拍视频 | 99久久婷婷国产综合精品青牛牛 | 国产日产精品一区四区介绍 | 久久最新网址 | 国产日韩a| 国内xxxx乱子另类 | 日本免费一区二区三区四区 | 精品国产呦系列在线看 | 久久影城 | 欧美一a一片一级一片 | 91网视频在线观看 | 在线成人免费网站 | 欧美福利视频一区二区三区 | 久久蜜桃香蕉精品一区二区三区 | 成人在线网站 | 久久亚洲激情 | 久草欧美 | 美女亚洲综合 | 黄色二区三区 | h色视频网站 | 九九精品影院 | 麻豆传传媒久久久爱 | av电影免费播放 | 欧美日韩免费一区 | 欧美天堂一区 | 成人影片在线免费观看 | 九色91视频 | 一级黄色免费观看 | 沉沦的校花奴性郑依婷c到失禁 | 亚洲无毛av | 中文字幕国产欧美 |