Попробуйте, попробуйте! & пытаться? В чем разница, и когда использовать каждый?

В Swift 2.0 Apple представила новый способ обработки ошибок (do-try-catch). И несколько дней назад в Beta 6 было введено еще более новое ключевое слово (try?). Кроме того, я знал, что могу использовать try!. Какая разница между тремя ключевыми словами и когда их использовать?

Ответ 1

Обновлено для Swift 5.1

Предположим, следующая функция метания:

enum ThrowableError: Error {

    case badError(howBad: Int)
}

func doSomething(everythingIsFine: Bool = false) throws -> String {

  if everythingIsFine {
      return "Everything is ok"
  } else {
      throw ThrowableError.badError(howBad: 4)
  }
}

попробовать

У вас есть 2 варианта при попытке вызвать функцию, которая может выдать.

Вы можете взять на себя ответственность за обработку ошибок, окружив свой вызов блоком do-catch:

do {
    let result = try doSomething()
}
catch ThrowableError.badError(let howBad) {
    // Here you know about the error
    // Feel free to handle or to re-throw

    // 1. Handle
    print("Bad Error (How Bad Level: \(howBad)")

    // 2. Re-throw
    throw ThrowableError.badError(howBad: howBad)
}

Или просто попробуйте вызвать функцию и передать ошибку по следующему абоненту в цепочке вызовов:

func doSomeOtherThing() throws -> Void {    
    // Not within a do-catch block.
    // Any errors will be re-thrown to callers.
    let result = try doSomething()
}

попробовать!

Что происходит, когда вы пытаетесь получить доступ к неявно развернутому необязательному файлу с нулем внутри него? Да, правда, приложение будет CRASH! То же самое и с попыткой! он в основном игнорирует цепочку ошибок и объявляет ситуацию "сделай или умри". Если вызванная функция не выдает никаких ошибок, все идет хорошо. Но если произошел сбой и возникла ошибка, ваше приложение просто рухнет.

let result = try! doSomething() // if an error was thrown, CRASH!

попробовать?

Новое ключевое слово, которое было введено в бета-версии Xcode 7. Оно возвращает необязательное значение, которое разворачивает успешные значения и возвращает ошибку, возвращая ноль.

if let result = try? doSomething() {
    // doSomething succeeded, and result is unwrapped.
} else {
    // Ouch, doSomething() threw an error.
}

Или мы можем использовать охрану:

guard let result = try? doSomething() else {
    // Ouch, doSomething() threw an error.
}
// doSomething succeeded, and result is unwrapped.

Последнее замечание, используя примечание try?, что вы отбрасываете произошедшую ошибку, поскольку она переведена в ноль. Используйте попробовать? когда вы сосредотачиваетесь больше на успехах и неудачах, а не на том, почему что-то не так.

Использование оператора объединения?

Вы можете использовать оператор объединения? с пробовать? предоставить значение по умолчанию в случае сбоя:

let result = (try? doSomething()) ?? "Default Value"
print(result) // Default Value

Ответ 2

try используется с оператором do-catch и позволяет более детально подходить к обработке ошибок.

пытаться? игнорирует наши ошибки и установит их на ноль, если они произойдут.

пытаться! force разворачивает ваш код и гарантирует, что наша функция никогда не столкнется с ошибкой. В случае, если наша функция выдает ошибку, наше приложение просто вылетает.