Swift 5.2 - was ist neu?

Die erste Beta von Swift 5.2 wurde gerade in der Beta von Xcode 11.4 veröffentlicht. Die Sprache wurde geändert, der Code und der verwendete Speicher wurden reduziert, und es wurde ein neues Diagnosesystem eingeführt, das eine schnellere Fehlererkennung ermöglicht.

Verwenden von KeyPath-Ausdrücken als Funktionen


Wir definieren folgende Struktur:

struct User {
    let name: String
    let age: Int
    let bestFriend: String?

    var canVote: Bool {
        age >= 18
    }
}

Lassen Sie uns einige Instanzen unserer Struktur erstellen und sie in ein Array einfügen:

let eric = User(name: "Eric Effiong", age: 18, bestFriend: "Otis Milburn")
let maeve = User(name: "Maeve Wiley", age: 19, bestFriend: nil)
let otis = User(name: "Otis Milburn", age: 17, bestFriend: "Eric Effiong")
let users = [eric, maeve, otis]

Nun Achtung: Wenn Sie eine Reihe von Namen aller Benutzer benötigen, können Sie dies wie folgt tun:

let userNames = users.map(\.name)
print(userNames)

Zuvor mussten wir einen Verschluss verwenden:

let oldUserNames = users.map { $0.name }

Auf die gleiche neue Weise können Sie alle Benutzer erhalten, die abstimmen können:

let voters = users.filter(\.canVote)

Und hier bekommen wir alle, die einen besten Freund haben:

let bestFriends = users.compactMap(\.bestFriend)

Werte für benutzerdefinierte Typen


Erstellen Sie eine Würfelstruktur mit lowerbound und upperbound Eigenschaften, und fügen Sie dann die callAsFunction Funktion . Jedes Mal, wenn wir den Würfelwert erhalten, erhalten wir einen zufälligen Wert:

struct Dice {
    var lowerBound: Int
    var upperBound: Int

    func callAsFunction() -> Int {
        (lowerBound...upperBound).randomElement()!
    }
}

let d6 = Dice(lowerBound: 1, upperBound: 6)
let roll1 = d6()
print(roll1)

Hier erhalten wir eine Zufallszahl von 1 bis 6, und dies ist völlig identisch mit einem direkten Aufruf von callAsFunction (). Wir könnten das Gleiche tun:

let d12 = Dice(lowerBound: 1, upperBound: 12)
let roll2 = d12.callAsFunction()
print(roll2)

Swift wählt automatisch den richtigen Aufruf basierend auf der Definition von callAsFunction () aus. Sie können beispielsweise mehrere Parameter hinzufügen, den Rückgabewert ändern und die Methode bei Bedarf sogar als mutierend markieren.

Hier erstellen wir eine StepCounter- Struktur , die die Anzahl der durchgeführten Schritte erfasst und signalisiert, ob die Anzahl der abgeschlossenen Schritte 10.000 erreicht hat:

struct StepCounter {
    var steps = 0

    mutating func callAsFunction(count: Int) -> Bool {
        steps += count
        print(steps)
        return steps > 10_000
    }
}

var steps = StepCounter()
let targetReached = steps(count: 10)

callAsFunction () unterstützt auch Throws und Rethrows, und Sie können mehrere CallAsFunction () -Methoden definieren, wie bei regulärer Überladung.

Der Index kann Standardargumente deklarieren


Wenn Sie einem Typ Indizes hinzufügen, können Sie die Standardargumente verwenden. Wenn wir beispielsweise eine PoliceForce- Struktur mit einem benutzerdefinierten Index zum Auflisten von Beamten in der Einheit haben, können wir einen Standardparameter hinzufügen, um ihn zurückzugeben, wenn das Array außerhalb seiner Grenzen gelesen wird:

struct PoliceForce {
    var officers: [String]

    subscript(index: Int, default default: String = "Unknown") -> String {
        if index >= 0 && index < officers.count {
            return officers[index]
        } else {
            return `default`
        }
    }
}

let force = PoliceForce(officers: ["Amy", "Jake", "Rosa", "Terry"])
print(force[0])
print(force[5])

Hier erhalten wir "Amy" und dann "Unbekannt" in der Ausgabe, da wir kein Array-Element mit Index 5 haben.

Da wir den Standardwert geschrieben haben, können wir einen benutzerdefinierten Wert festlegen, wie:

print(force[-1, default: "The Vulture"])

Neue und verbesserte Diagnose


Swift 5.2 führt eine neue Diagnosearchitektur ein, deren Ziel es ist, die Qualität und Genauigkeit von Xcode-Entwicklungsfehlermeldungen zu verbessern. Dies macht sich insbesondere bei der Arbeit mit SwiftUI-Code bemerkbar, bei dem Swift häufig falsch positive Fehlermeldungen generiert.

Betrachten Sie beispielsweise den folgenden Code:

struct ContentView: View {
    @State private var name = 0

    var body: some View {
        VStack {
            Text("What is your name?")
            TextField("Name", text: $name)
                .frame(maxWidth: 300)
        }
    }
}

Hier versuchen wir, view TextField einer Ganzzahl zuzuordnen ZustandEigenschaft, die falsch ist. In diesem Fall generiert Swift 5.1 einen Fehler für den Frame () -Modifikator 'Int', der nicht in 'CGFloat?' Konvertiert werden kann. Swift 5.2 und höher erkennen den Fehler bei der Bindung von $ name jedoch korrekt: Der Wert vom Typ 'Binding' kann nicht in den erwarteten Argumenttyp 'Binding' konvertiert werden.

Source: https://habr.com/ru/post/undefined/


All Articles