所以我喜欢声明变量来保存返回值,然后在下一行返回所述变量,从而使调试我的代码变得容易,我可以在返回行设置一个断点并查看它返回的值。我在任何地方都使用它,它使我的所有代码都更容易调试。
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let cellCount = models.count
return cellCount
}
但是,您会遇到这样一种情况,即您必须满足选项和不同的条件才能使您的方法有意义。守卫声明非常适合确保满足某些条件,同时不会引入末日金字塔。
但是提前返回的问题是您从您的方法中至少获得了两个退出点(因为在这种情况下guard
需要 a return
),这使得调试变得更加困难。
// Instantiate using dependency injection
private let reachability: ReachabilityProtocol
private let apiClient: APIClientProtocol
// Returns true if could start login request, else false
func loginUser(username: String, password: String) -> Bool {
defer {
// Not possible, would be nice! Return value would be an implicitly declared variable
// exaclty like the variables 'newValue' and 'oldValue' in property observers!
print("return value: \(returnValue)")
}
guard reachability.isOnline && !username.isEmpty && !password.isEmpty { return false }
apiClient.loginUser(username, password: password)
return true
}
如果 Swift 3.X 能让defer 语句能够捕获返回值,那该多好,不是吗?
这将使调试变得更加容易,同时仍然使用guard
和早期返回。我不知道在编写编译器等方面有什么意义,但感觉在即将到来的 Swift 版本中实现这一点并不难?
你能想出一种不同的方法来实现单点读取具有多个退出点的方法的返回值吗?(无需等待我建议的改进defer
?)
编辑:
我上面的登录示例不是一个完美的示例,对不起,我为什么要编写这样的代码?哈哈!但是还有很多其他类似的场景,可能是这样的,使用do-try-catch
也会使代码难以调试:
// We don't know the return value of this function! Makes it hard to debug!
func fetchUserByFirstName(firstName: String, andLastName lastName: String, fromContext context: NSManagedObjectContext) -> User? {
defer {
// Not possible, would be nice! Return value would be an implicitly declared variable
// exaclty like the variables 'newValue' and 'oldValue' in property observers!
print("return value: \(returnValue)")
}
guard !firstName.isEmpty else { print("firstName can't be empty"); return nil }
guard !lastName.isEmpty else { print("lastName can't be empty"); return nil }
// Imagine we have some kind of debug user... Does not really make sense, but good for making a point.
guard firstName != "DEBUG" else { return User.debugUser }
let fetchRequest = NSFetchRequest(entityName: Users.entityName)
let predicate = NSPredicate(format: "firstName == \(firstName) AND lastName == \(lastName)")
fetchRequest.predicate = predicate
do {
let user = try context.executeFetchRequest(fetchRequest)
return user
} catch let error as NSError {
print("Error fetching user: \(error)")
}
return nil
}