dene dene! & Deneyin? fark nedir ve her biri ne zaman kullanılır?


172

In Swift 2.0 Apple hataları (do-try-catch) işlemek için yeni bir yol sundu. Ve birkaç gün önce Beta 6'da daha da yeni bir anahtar kelime tanıtıldı ( try?). Ayrıca kullanabileceğimi biliyordum try!. 3 anahtar kelime arasındaki fark nedir ve her biri ne zaman kullanılır?

Yanıtlar:


316

Swift 5.1 için güncellendi

Aşağıdaki fırlatma işlevini varsayalım:

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

Deneyin

Atabilecek bir işlevi çağırmayı denediğinizde 2 seçeneğiniz vardır.

Çağrınızı bir do-catch bloğu içinde çevreleyerek hataları ele alma sorumluluğunu üstlenebilirsiniz :

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

Veya işlevi çağırmayı deneyin ve hatayı çağrı zincirindeki bir sonraki arayana iletin:

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

Deneyin!

İçinde sıfır bulunan örtük olarak açılmamış isteğe bağlı bir öğeye erişmeye çalıştığınızda ne olur? Evet, doğru, uygulama ezilecek! Aynı şey deneyin! temel olarak hata zincirini yok sayar ve bir “yap ya da öl” durumu bildirir. Aranan işlev herhangi bir hata atmazsa, her şey yolunda gider. Ancak başarısız olursa ve bir hata attıysa, uygulamanız basitçe çökecektir .

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

Deneyin?

Xcode 7 beta 6'da tanıtılan yeni bir anahtar kelime. Başarılı değerleri açığa çıkaran ve nil döndürerek hata yakalayan bir isteğe bağlı döndürür .

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

Veya korumayı kullanabiliriz:

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

Burada son bir not, try?bir nile çevrildiğinden oluşan hatayı attığınızı not ederek. Try kullan? şeylerin neden başarısız olduğuna değil, başarılara ve başarısızlığa daha fazla odaklanırken.

Birleştirme Operatörünü Kullanma ??

Birleştirme operatörünü kullanabilirsiniz ?? denemek? hata durumunda varsayılan bir değer sağlamak için:

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

İkinci kod örneğiniz ( let result = try doSomething() // Not within a do-catch block), bildirilen bir yöntemle çağrılmalıdır throws, değil mi? Peki, doSomething()başarısız olursa, dış yöntem de öyle (sırayla)?
Nicolas Miari

Eski iş parçacığı ve bugün hariç tüm (Swift 4, Xcode 9.1) denemek? sonucu otomatik olarak açmaz. Manuel olarak açmanız için normal bir isteğe bağlı olarak bırakır. Bunun Swift 2/3'ten bu yana değişip değişmediğinden emin değilim ancak dokümanlar için olduğundan emin olun: developer.apple.com/library/content/documentation/Swift/… (bkz. Hataları İsteğe Bağlı Değerlere Dönüştürme ). Btw deneyin büyük açıklama.
the_dude_abides

1
hızlı 4, denemek? projemdeki 'try' ifadeleri içinde hiçbir fırlatma fonksiyonuna çağrı yapılmazsa kaldırılmaz.
aznelite89

7
Ayrıca kullanabilirsiniz try?ile ??size bir satırda varsayılan bir değer tanımlayalım diye:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"
itMaxence
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.