Так что я люблю объявление переменных для хранения возвращаемого значения, а затем возвращает указанную переменную на следующей строке, что упрощает отладку моего кода, я могу просто установить точку останова на линии возврата и посмотреть, какое значение оно возвращает. Я использую это везде, и это делает мой код намного легче отлаживать.Swift: упростить отладку, улавливая возвращаемое значение в заявлении о текущем состоянии
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let cellCount = models.count
return cellCount
}
Но тогда у вас есть сценарий, где у вас есть и другие УСТРОЙСТВА условия, которые должны быть выполнены для того, чтобы ваш метод к имеет смысл. The guard statement отлично подходит для обеспечения соответствия определенным условиям, а не ввода pyramids of doom.
Но проблема с ранней отдачей заключается в том, что вы получаете как минимум две точки выхода (потому что guard
требует в этом контексте 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 бы the defer statement смог поймать возвращаемое значение, не так ли?
Это позволит сделать отладку намного проще, в то же время используя 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
}
Да, именно то, что я обычно делаю! :) Спасибо, что нашли время и предложили это, хотя! :) Я предполагаю, что это единственный способ на данный момент ... – Sajjon
Добавлено второе решение, которое хуже ;-) – vacawama
Ничего себе! Я даже не знал, что можно объявить функцию внутри функции! Это очень творческие решения! – Sajjon