Напишите функцию высшего порядка, которая бросает только если бросает её замыкание
Напишите обобщённую функцию firstMatch, которая возвращает первый элемент массива, удовлетворяющий замыканию-предикату, или nil, если совпадений нет.
Требования:
- Предикат сам может бросать;
firstMatchдолжна бросать только когда бросает предикат. - Вызывающий с незабрасывающим предикатом должен вызывать
firstMatchбезtry. - Не добавляйте собственную обработку ошибок внутри функции.
func firstMatch<T>(in items: [T], where predicate: (T) throws -> Bool) rethrows -> T? {
// ваш код здесь
}
Допишите реализацию.
rethrows помечает функцию, которая бросает только когда бросает переданное ей замыкание. С незабрасывающим замыканием вызывающий обходится без try; с забрасывающим — вызов становится throwing. Обычный throws заставлял бы каждого вызывающего писать try.
- ✗Думают, что
rethrowsперехватывает или глушит ошибку замыкания - ✗Считают, что
rethrows-функция требуетtryдаже с незабрасывающим замыканием - ✗Путают
rethrowsс повтором операции при сбое
- →Почему
rethrows-функция не может бросить собственную ошибку? - →Как меняется требование
tryу вызывающего в зависимости от переданного замыкания?
rethrows lets a function forward its closure's error without declaring one of its own:
func firstMatch<T>(in items: [T], where predicate: (T) throws -> Bool) rethrows -> T? {
for item in items {
if try predicate(item) { // try обязателен здесь, внутри тела
return item
}
}
return nil
}
// незабрасывающий предикат — вызов без try
let n = firstMatch(in: [1, 2, 3]) { $0 > 1 }
// забрасывающий предикат — вызов требует try
let m = try firstMatch(in: users) { try validate($0) }
Внутри тела try predicate(item) обязателен. Но снаружи требование try зависит от переданного замыкания: незабрасывающее — вызывающий пишет без try; забрасывающее — вызов становится throwing. throws вместо rethrows заставил бы даже первого вызывающего писать try и catch, хотя ошибки быть не может. Именно поэтому map, filter, first(where:) в стандартной библиотеке объявлены через rethrows.