После поиска для некоторых ссылок, чтобы понять это, к сожалению, я не мог найти полезную и просто - описание о понимании различия между бросает
и возвращает
. Это сбивает с толку, когда пытаются понять, как мы должны их использовать.
Я хотел бы упомянуть, что я знаком с -по умолчанию - "бросков" своей простейшей форме распространения ошибки, а именно:
enum CustomError: Error {
case potato
case tomato
}
func throwCustomError(_ string: String) throws {
if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
throw CustomError.potato
}
if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
throw CustomError.tomato
}
}
do {
try throwCustomError("potato")
} catch let error as CustomError {
switch error {
case .potato:
print("potatos catched") // potatos catched
case .tomato:
print("tomato catched")
}
}
Пока все хорошо, но проблема возникает тогда, когда:
func throwCustomError(function:(String) throws -> ()) throws {
try function("throws string")
}
func rethrowCustomError(function:(String) throws -> ()) rethrows {
try function("rethrows string")
}
rethrowCustomError { string in
print(string) // rethrows string
}
try throwCustomError { string in
print(string) // throws string
}
что я до сих пор знаю, когда вы вызываете функцию, которая "бросков" с ним нужно обращаться на "попробовать", в отличие от возвращает
. Ну и что?! Что такое логика, мы должны следовать при принятии решения об использовании бросает
или возвращает
?
От "Declarations" в Свифт книги:
повторное функций и методов
функция или метод может быть объявлен с ключевым словом в
возвращает
в и GT; показывают, что он выдает ошибку только если один из его функции параметров вызывает ошибку. Эти функции и методы известны как повторное функций и повторное методов. Повторное функций и методы должны иметь по крайней мере один метательный параметра функции.
Типичным примером является ["карта"] (https://developer.apple.com/documentation/swift/array/2908681-map) метод:
public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
Если "карта" называется не бросать преобразование, его не бросишь сама по себе ошибка, а можно назвать без "попробовать":
// Example 1:
let a = [1, 2, 3]
func f1(n: Int) -> Int {
return n * n
}
let a1 = a.map(f1)
Но если "карта" называется с метательной закрытия, то сам может бросить
и должен быть вызван С попробовать
:
// Example 2:
let a = [1, 2, 3]
enum CustomError: Error {
case illegalArgument
}
func f2(n: Int) throws -> Int {
guard n >= 0 else {
throw CustomError.illegalArgument
}
return n*n
}
do {
let a2 = try a.map(f2)
} catch {
// ...
}
бросает
вместо возвращает
тогда вы бы
надо называть его "попробовать" даже в Примере 1,
что есть "неудобно" и раздувает код ненужными. То же справедливо и для других методов от SWIFT стандартной библиотеки
которые принимают параметры функции: фильтр()
, индекс(где:)
, цикл foreach()
и многое другое.
В вашем случае,
func throwCustomError(function:(String) throws -> ()) throws
обозначает функцию, которая может выдавать ошибку, даже если она вызывается с не бросать аргумент, а
func rethrowCustomError(function:(String) throws -> ()) rethrows
обозначает функцию, которая выдает ошибку только если с бросив аргумент.
Грубо говоря, возвращает
для функций, которые не бросают
ошибки "на свои", но лишь "Вперед" и ошибки с их функцией
параметры.
Просто добавить что-то вместе с Мартином'ы ответ. Не бросать функцию с той же сигнатурой, функция метания считается подтип
функции кидание. Именно поэтому возвращает может определить, какая она есть, и требуется только "попробовать", когда функции парам тоже кидается, но все равно принимает ту же сигнатуру функции, которая не'т бросить. Это'ы очень удобный способ, чтобы иметь только использовать делать блок try, когда Функ парам бросает, но другой код в функцию Не'т бросить ошибку.