简评:
函数是一个组织在一起语句集合,以执行特定任务。Swift 函数类似于简单 C 函数以及复杂的 Objective C 语言函数。 它使我们能够通过函数调用内部的局部和全局参数值。 像其他任何语言一样 swift 函数也遵循相同的步骤。
Swift 函数包含参数类型和返回类型。
函数提前返回主要的好处是:将每个错误处理进行分离,审查代码时不需要考虑多种复杂异常,我们可以吧注意力集中在也业务逻辑中,调试代码时可以直接在异常中打断点。
提前返回
首先来看一下需要改进的代码示例,我们构建一个笔记应用使用 NotificationCenter API,当笔记内容有变化时 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() } } } }
上面的代码可以很好的工作,但是可读性差了点。因为这段代码包含多重缩进和类型转换。我们来尝试改进这段代码。
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() } }
将函数提前返回能够将功能失败的情况处理得更加清晰,这不仅提高了可读性(更少的缩进,更少的嵌套),同时也有利于单元测试。
我们可以进一步改进代码,将获取 noteID 和类型转换的代码放在 Notification Extension 中,这样就将 handleChangeNotification 业务逻辑和具体细节分离开来。修改后代码如下所示:
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() } }
这种结构还大大简化了调试的难度,我们可以直接在每个 guard 中 return 中添加断点来截获所有失败情况,而不需要单步执行所有逻辑。
条件构造
当构造一个对象实例,非常普遍的需求是需要构建哪类对象取决于一系列的条件。
例如,启动应用程序时显示哪个 view controller 取决于:
我们对这些条件的的实现可能是一系列的 if 和 else 语句,如下所示:
func showInitialViewController() { if loginManager.isUserLoggedIn { if tutorialManager.isOnboardingCompleted { navigationController.viewControllers = [HomeViewController()] } else { navigationController.viewControllers = [OnboardingViewController()] } } else { navigationController.viewControllers = [LoginViewController()] } }
同样的提前返回和 guard 语句可以提升代码可读性,但是现在这种情况不是处理失败情况,而是在不同条件下构建不同 view controller。
现在来改进这段代码,使用轻量级的工程模式,将构造初始界面移动到专门的函数中,该函数返回匹配条件的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 方法是个纯函数(不影响外部状态,固定输入能够得到固定输出),实际上影响外部状态的只有一个地方 navigationController.viewControllers = [viewController] ,(在日常开发中状态如果没有得到很好的控制很容易引起 bug,所以使用更少状态和减少对状态的修改可以一定程度上减少 bug 出现的几率)。
条件控制
最后我们来看看,函数如何简化复杂的条件逻辑。我们来构建一个 view controller 来显示社交应用的评论功能,如果满足三个条件则运行用户对评论进行编辑。代码如下:
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 嵌套逻辑,每次重新审查代码都会比较困扰,更具之前的经验我们可以对代码进行优化,添加 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) } ... } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍实例详解易语言返回函数,包括了实例详解易语言返回函数的使用技巧和注意事项,需要的朋友参考一下 返回()是易语言的重要函数,很多函数都有返回值,就是用这个函数返回。 非无私奉献,拒绝看经验不回复,学懂了记得按照下面做: 具体操作请看图。 1、易语言新建一个windows窗口 点击进入代码编辑区 2、我们首先定义一个变量a 整数型 3、然后我们输入计次循环首 这个具体用法请看 易语言计次
本文向大家介绍PHP函数引用返回的实例详解,包括了PHP函数引用返回的实例详解的使用技巧和注意事项,需要的朋友参考一下 引用返回 手册里是这么写的:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用 当你想将函数的返回引用绑定到某个变量时,PHP允许你这么做: 可见,想让函数返回引用,必须在
本文向大家介绍Swift传递和返回函数,包括了Swift传递和返回函数的使用技巧和注意事项,需要的朋友参考一下 示例 以下函数返回另一个函数作为其结果,可以稍后将其分配给变量并调用:
我在ViewDidLoad函数中有一些代码,它将在调用堆栈的末尾设置一个类变量。我试图重构代码,使其成为一个单独的函数,它将返回值,而不是设置类变量。 由于我缺乏swift知识,我不确定哪里出了问题,我的函数似乎返回得太厄尔了,因为我可以在调试器中告诉我,它在被设置为之前跳转到return。 我还可以在调试器中看到,内部函数在返回主函数后调用。 如何等待内部调用完成后再返回?或者什么是正确的快速方
我需要从我的FastAPI路径操作返回一个响应,但在此之前,我想发送一个缓慢的请求,我不需要等待该请求的结果,如果有任何错误,只需记录错误。我可以通过Python和FastAPI做到这一点吗?我不想将芹菜添加到项目中。 这是我目前掌握的情况,但它是同步运行的:
问题内容: 我正在尝试进行此扩展: 但是我得到了编译错误: 错误:无法将类型’UIViewController’的返回表达式转换为类型’Self’ 可能吗?我也想做到 问题答案: 与在Swift的类扩展函数中使用’self’类似,您可以定义一个通用的辅助方法,该方法可以从调用上下文中推断出self的类型: 然后 进行编译,并将类型推断为。 Swift 3 更新 : 另一种可能的解决方案,使用: