Рекурсия — это процесс, в котором функция вызывает саму себя напрямую или косвенно. Это мощный инструмент для решения задач, которые можно разбить на более мелкие подзадачи того же типа.
func factorial(_ n: Int) -> Int {
guard n > 1 else { return 1 } // Базовый случай
return n * factorial(n - 1) // Рекурсивный случай
}
Базовый случай (Base case):
if n <= 1 { return 1 }
Рекурсивный случай (Recursive case):
return n * factorial(n - 1)
Всегда определяйте базовый случай: Без него рекурсия будет бесконечной, что приведет к переполнению стека.
Рекурсивный вызов должен приближать к базовому случаю: Каждый вызов должен уменьшать проблему.
Учитывайте глубину рекурсии: В Swift глубина стека ограничена (```64K вызовов).
extension UIView {
func findAllSubviews<T: UIView>(ofType type: T.Type) -> [T] {
var result = subviews.compactMap { $0 as? T }
for subview in subviews {
result += subview.findAllSubviews(ofType: type)
}
return result
}
}
func listFiles(in directory: String, indent: String = "") {
let fileManager = FileManager.default
guard let files = try? fileManager.contentsOfDirectory(atPath: directory) else { return }
for file in files {
print(indent + file)
let path = directory + "/" + file
var isDir: ObjCBool = false
if fileManager.fileExists(atPath: path, isDirectory: &isDir), isDir.boolValue {
listFiles(in: path, indent: indent + " ") // Рекурсивный вызов
}
}
}
Swift оптимизирует хвостовую рекурсию через tailrec
(в некоторых случаях).
func factorial(_ n: Int, _ accumulator: Int = 1) -> Int {
guard n > 1 else { return accumulator }
return factorial(n - 1, n * accumulator) // Хвостовая рекурсия
}
Для избежания повторных вычислений.
var memo = [Int: Int]()
func fibonacci(_ n: Int) -> Int {
if let result = memo[n] { return result }
guard n > 1 else { return n }
let result = fibonacci(n - 1) + fibonacci(n - 2)
memo[n] = result
return result
}
Хорошие кандидаты:
Плохие кандидаты:
Итерации (циклы):
func factorialIterative(_ n: Int) -> Int {
var result = 1
for i in 1...n {
result *= i
}
return result
}
Стек + цикл (имитация рекурсии): Полезно для глубокой рекурсии.
Рекурсия — это элегантный способ решения задач, которые естественным образом можно разделить на подобные подзадачи. В iOS разработке она полезна для работы с иерархическими структурами, но требует осторожности из-за ограничений стека. Всегда проверяйте:
Для production-кода с большими данными часто предпочтительнее итеративные решения.