Swift 5.1

Vorige Woche wurde Swift 5.1 ist veröffentlicht. Es zeichnet sich durch vollständige Kompatibilität zu Swift 5.0 und einige neue Features aus. Dass nur ein Bruchteil davon für typische App-Entwickler relevant ist, kann wohl als Zeichen dafür gesehen werden, dass Swift allmählich wirklich ausgereift ist.

Apple verspricht außerdem, dass Swift Module Compatibility bietet. Das bedeutet, dass unter Swift 5.1 erzeugte und kompilierte Bibliotheken ohne Änderungen (und ohne Neukompilieren) mit zukünftigen Swift-Versionen kooperieren.

In diesem Beitrag fasse ich ganz kurz die wichtigsten neuen Features zusammen. (Ein eigener Artikel über die neue Bibliothek SwiftUI ist geplant, aber ich kann noch nicht sagen, wann ich dazu komme.)

Zugriff auf statische Methoden mit Self

Bisher war es ziemlich umständlich, in einem Typ auf statische Methoden zuzugreifen: Dazu musste der Typname vorangestellt werden. Alternativen waren auch self.dynamicType oder type(of: self) möglich. In Swift 5.1 verwenden Sie — wesentlich naheliegender — Self (SE-0068).

struct OtherStruct {
  static func m1() -> Int {  // statische Methode
    return 42
  }
  func m2() -> Int {        // nicht-statische Methode
    // Zugriff auf m1() in Swift 5.0
    let tst1 = OtherStruct.m1()
    let tst2 = self.dynamicType.m1()  // deprecated
    let tst3 = type(of: self).m1()
    // viel eleganter in Swift 5.1
    return Self.m1() + 17
  }
}

Statische Subscripts

Das schon bisher verfügbare Schlüsselwort subscript ermöglichte es, eine Methoden zu formulieren, die in der Folge wie bei einem Array einen Zugriff auf Elemente in der Form obj[index] ermöglichte. Neu in Swift 5.1 ist, dass derartige Subscripts nun auch für statische Daten erlaubt sind (SE-0254).

Das folgende Beispiel zeigt zuerst Code, mit dem in Swift 5.0 ein statischer Key/Value-Speicher realisiert werden kann:

// in Swift 5.0
public enum Store1 {
  private static var data = [String: String]()
  static func get(_ key: String) -> String? {
    return data[key]
  }
  static func set(_ key: String, _ newValue: String) {
    data[key] = newValue
  }
}
Store1.set("somekey", "somevalue")
let result1 = Store1.get("somekey") ?? "not found"

Swift 5.1 erlaubt hier den Einsatz von subscript und führt zu klarerem Code, vor allem bei der Anwendung:

// in Swift 5.1
public enum Store2 {
  private static var data = [String: String]()
  static subscript(_ key: String) -> String? {
    get {
      return data[key]
    }
    set {
      data[key] = newValue
    }
  }
}
Store2["somekey"] = "somevalue"
let result2 = Store2["somekey"] ?? "not found"  // "somevalue"

Defaultparameter in struct-Konstruktoren

Wie bisher erzeugt Swift bei structs einen Default-Konstruktor. Neu ist, dass in diesem Konstruktor nun alle Parameter mit Defaultwerten optional sind (SE-0242):

struct MyStruct {
  var a: Double
  var b: Int = 123
  var c: String = "abc"
}
let data1 = MyStruct(a: 12.3, b: 42, c: "efg") // bisher schon möglich
let data2 = MyStruct(a: 12.3)                  // neu

Implizites return

Bei Closures, die mit nur einem Ausdruck eine Funktion/Methode definieren, können Sie nun auf return verzichten. Das folgende Beispiel stammt direkt aus SE-0255:

// Swift 5.0
extension Sequence where Element == Int {
   func sum() -> Element {
        return reduce(0, +)
    }
}

// Swift 5.1: kein return mehr erforderlich
extension Sequence where Element == Int {
   func sum() -> Element {
        reduce(0, +)
    }
}

Sonstiges

Einige Neuerungen hat es auch in der Swift Standardbibliothek gegeben:

Quellen