prova prova! & provare? qual è la differenza e quando usarli?


172

In Swift 2.0 , Apple ha introdotto un nuovo modo di gestire gli errori (do-try-catch). E pochi giorni fa in Beta 6 è stata introdotta una parola chiave ancora più recente ( try?). Inoltre, sapevo che posso usare try!. Qual è la differenza tra le 3 parole chiave e quando usarle?

Risposte:


316

Aggiornato per Swift 5.1

Assumi la seguente funzione di lancio:

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)
  }
}

provare

Hai 2 opzioni quando provi a chiamare una funzione che può essere lanciata.

Puoi assumerti la responsabilità di gestire gli errori circondando la chiamata all'interno di un blocco 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)
}

Oppure prova a chiamare la funzione e passa l'errore al chiamante successivo nella catena di chiamate:

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

provare!

Cosa succede quando si tenta di accedere a un accessorio implicitamente non scartato con un valore al suo interno? Sì, vero, l'app CRASH! Lo stesso vale per provare! fondamentalmente ignora la catena di errori e dichiara una situazione "do or die". Se la funzione chiamata non ha generato alcun errore, tutto va bene. Ma se fallisce e genera un errore, l'applicazione si bloccherà semplicemente .

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

provare?

Una nuova parola chiave che è stata introdotta in Xcode 7 beta 6. Restituisce un facoltativo che scartare i valori di successo e rileva l'errore restituendo zero.

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

Oppure possiamo usare guard:

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

Un'ultima nota qui, usando la try?nota che stai scartando l'errore che si è verificato, poiché è tradotto in uno zero. Usa provare? quando ti stai concentrando di più sui successi e sugli insuccessi, non sul motivo per cui le cose sono fallite.

Usando l'operatore di coalescenza ??

Puoi usare l'operatore di coalescenza ?? con provare? per fornire un valore predefinito in caso di errore:

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

Il tuo secondo codice di esempio ( let result = try doSomething() // Not within a do-catch block) deve essere chiamato all'interno di un metodo dichiarato come throws, giusto? Quindi, se doSomething()fallisce, anche il metodo esterno (a sua volta)?
Nicolas Miari,

Vecchio thread e tutto, ma ho scoperto che oggi (Swift 4, Xcode 9.1) provare? non scartare automaticamente il risultato. Ti lascia come un normale optional per scartarlo manualmente. Non sono sicuro che sia cambiato da Swift 2/3 ma è per i documenti: developer.apple.com/library/content/documentation/Swift/… (vedi Conversione degli errori in valori opzionali ). Grande spiegazione di provare a proposito.
the_dude_abides il

1
in Swift 4, provare? non rimuove le chiamate "no" alle funzioni di lancio all'interno delle espressioni "try" nel mio progetto.
Aznelite89,

7
Puoi anche usarlo try?con ??così ti permetterebbe di definire un valore predefinito in una riga:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"
itMaxence
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.