Sobes.tech
Middle

Jak w Swift realizowane jest otwarcie (opcjonalne, kontrakty i inne mechanizmy)?

sobes.tech AI

Odpowiedź od AI

Opcjonalne w Swift reprezentują typ, który może zawierać wartość typu T (opakowaną wartość) lub nil, co oznacza brak wartości.

Główne mechanizmy pracy z opcjonalami:

  1. Wiązanie opcjonalne (if let, guard let): Bezpieczne wyodrębnianie wartości z opcjonalnego.

    • if let: Wyodrębnia wartość i przypisuje ją do tymczasowej stałej lub zmiennej, jeśli opcjonalny zawiera wartość. Blok kodu jest wykonywany tylko w tym przypadku.
      let optionalString: String? = "Hello"
      if let unwrappedString = optionalString {
          // unwrappedString ma typ String
      }
      
    • guard let: Wyodrębnia wartość. Jeśli opcjonalny jest nil, wykonywany jest blok else (zwykle aby opuścić bieżący zakres). Jeśli wartość zostanie pomyślnie wyodrębniona, jest dostępna po guard w bieżącym zakresie.
      func processString(_ optionalString: String?) {
          guard let unwrappedString = optionalString else {
              return // Wyjście z funkcji
          }
          // unwrappedString ma typ String dostępny tutaj
      }
      
  2. Łańcuch opcjonalny (?): Pozwala wywołać właściwości, metody i indeksy na opcjonalnym. Jeśli na którymkolwiek etapie łańcucha opcjonalny jest nil, cały łańcuch jest przerywany, a wynik ma typ opcjonalny zawierający nil.

    class Person {
        var job: Job?
    }
    
    class Job {
        var salary: Double?
    }
    
    let person: Person? = Person()
    person?.job = Job()
    let salary = person?.job?.salary // salary ma typ Double?
    
  3. Wymuszone wyodrębnianie (!): Niebezpieczne wyodrębnianie wartości. Prowadzi do błędu w czasie wykonywania (crash), jeśli opcjonalny zawiera nil. Należy używać z dużą ostrożnością, tylko gdy jest pewność, że opcjonalny nie jest nil.

    let requiredString: String! = "Must be present" // Opcjonalny domyślny
    let unwrappedString = requiredString! // Wymuszone wyodrębnianie
    
    let dangerousOptional: String? = nil
    // let crash = dangerousOptional! // Spowoduje błąd
    
  4. Operator koalescencji null (??): Zapewnia wartość domyślną, jeśli opcjonalny jest nil.

    let optionalValue: Int? = nil
    let definiteValue = optionalValue ?? 0 // definiteValue będzie 0
    
  5. Opcjonalne domyślnie wyodrębnione (!): Opcjonalne, które są automatycznie wyodrębniane podczas użycia. Deklaruje się je za pomocą !. Należy używać, gdy gwarantuje się, że wartość zostanie przypisana przed pierwszym użyciem, ale niekoniecznie podczas inicjalizacji (np. IBOutlets). Podczas dostępu, gdy wartość jest nil, występuje błąd w czasie wykonywania.

    var button: UIButton! // Zakłada się, że zostanie zainicjowany w viewDidLoad
    // button.setTitle("Tap me", for: .normal) // Automatyczne wyodrębnianie podczas użycia
    

"Kontrakty" w tym kontekście nie są odrębnym mechanizmem językowym Swift, podobnym do kontraktów w innych językach. Swift zapewnia bezpieczeństwo poprzez system typów, obejmujący opcjonalne i kontrolę dostępu, co pomaga wyrazić intencje i zapobiega błędom. Opcjonalne służą jako "kontrakt" wskazujący na możliwość braku wartości.