Ende März wurde Swift 5.2 für Xcode 11.4 veröffentlicht. Es hat die Fehlerdiagnose, die Abhängigkeitsanalyse und die SwiftPM-Funktionalität verbessert. Eine Übersicht über einige Änderungen wurde bereits auf Habré veröffentlicht. Im selben Artikel wird die Entwicklung der Sprache selbst mit möglichen Anwendungsbeispielen betrachtet.
SE-0249 KeyPath als Funktion
Die Verknüpfung fügt keyPath in eine Funktion ein, bei der der Eingabeparameter das Objekt selbst und das Ergebnis seine Eigenschaft ist.Schauen wir uns ein Beispiel an. Erstellen Sie eine Reihe einfacher Modelle:struct Model {
let isHidden: Bool
}
let modelArray = [Model(isHidden: true), Model(isHidden: false)]
Filtern Sie das Array nach der Eigenschaft isHidden. Unten sind 3 Beispiele mit dem gleichen Ergebnis:
let funcIsHidden: (Model) -> Bool = \.isHidden
modelArray.filter(funcIsHidden)
modelArray.filter(\.isHidden as (Model) -> Bool)
modelArray.filter(\.isHidden)
Die deklarierte Funktionalität funktioniert im folgenden Beispiel nicht:
let selfFunc: (Model) -> Model = \.self
modelArray.compactMap(selfFunc)
modelArray.compactMap(\.self as (Model) -> Model)
modelArray.compactMap(\.self)
Im Gegensatz zu keyPath funktioniert die automatische Vervollständigung nicht.Es ist praktisch, um mit Arrays in Funktionen wie Filtern, Zuordnen, Reduzieren, Sortieren und dergleichen zu arbeiten.SR-6118- Indizes können Standardeinstellungen enthalten
Alle Funktionsparameter können auf den Standardwert gesetzt werden. Erstellen Sie eine Box-Struktur, die ein Array von Elementen und eine Indexfunktion enthält, um darauf zuzugreifen.struct Box {
let items: [String]
subscript(_ index: Int = 0) -> String {
items[index]
}
}
Um nun auf das erste Element zuzugreifen, können Sie den Index weglassen:let box = Box(items: ["laptop, , mobile phone"])
let firstItem = box[]
SR-2189 Lokale Funktionen unterstützen Standardparameter aus der externen Sichtbarkeit
In der täglichen Praxis werden lokale Funktionen selten verwendet. Es kann schwierig sein, ihre Verwendung zu rechtfertigen. Trotzdem gebe ich zu, dass dies in bestimmten Fällen nützlich sein kann.Als Beispiel erstellen wir eine Funktion, in der wir eine lokale beschreiben:func getXPosition() {
func calculateWidth(x: CGFloat = minX) -> CGFloat { ... }
let minX: CGFloat = 0
...
}
Als Standardparameter für die Funktion berechneWeite können wir die Werte innerhalb der Funktion getXPosition verwenden.SE-0253 Verwenden von Werten als Funktionen
Mit der Funktionalität, ähnlich wie bei @dynamicCallable, können Sie einen Wert als Funktion verwenden. Aber es ist eine Implementierung des "statischen Aufrufs".In der Praxis ist alles sehr einfach: Um Funktionen aufzurufen, können Sie Werte als Methoden bezeichnen.Erstellen Sie eine Player-Struktur:struct Player {
private(set) var isRunning = false
mutating func callAsFunction() {
isRunning.toggle()
}
}
Erstellen Sie eine Instanz von Player und bezeichnen Sie sie als Funktion:var player = Player()
print(player.isRunning)
player()
print(player.isRunning)
Gleichzeitig ist es verboten, ein Objekt als Funktion zu gießen und daher zu übergeben:
let playerAsFunc = player as () -> Void
Sie können einer Klasse, Struktur oder einem Protokoll so viele Methoden wie callAsFunction hinzufügen:extension Player {
func callAsFunction(isRunning: Bool = false) throws { ... }
func callAsFunction() -> Bool { ... }
}
Die Anwendung ist in Werten möglich, die mathematische Funktionen, komplexe Ausdrücke oder in Fällen sind, in denen der Wert eine dominante Funktion hat. Trotzdem sollten Sie diese Funktionalität nicht missbrauchen, da sie irreführend sein kann.SR-4206 Fehler behoben, bei dem die Funktion mit generischen Parametern überschrieben wurde
Wenn Sie die Funktion überschreiben, können Sie den generischen Typ nicht mehr ändern oder einschränken. Erstellen Sie beispielsweise eine CarBuilder-Klasse und erben Sie sie, indem Sie die add-Methode überschreiben:protocol PowerfullEngine { }
class CarBuilder {
func add<T>(engine: T) {}
}
class MercedesBuilder: CarBuilder {
override func add<T>(engine: T) {}
override func add<T: PowerfullEngine>(engine: T) {}
}
SR-11298 Das Erweitern eines Protokolls ohne Klasseneinschränkungen erbt diese Einschränkung
Im Falle von Selbstbeschränkungen gilt für die Erweiterung die Beschränkung.Erstellen Sie beispielsweise das Menü- und Erweiterungsprotokoll mit einer Klasseneinschränkung:protocol Menu {}
class SideMenu: Menu {
var sectionHeight = 0
}
extension Menu where Self: SideMenu {
var menuHeight: Int {
get { sectionHeight * 20 }
set { sectionHeight = newValue / 20 }
}
}
Gleichzeitig mutiert der Setter nicht, als ob das Protokoll eine Klassenbeschränkung hätte.SR-11429 Casting für Funktionen mit Beschriftungen
Beim Casting werden Funktionen zum Schreiben von Etiketten jetzt entfernt. Dank dessen können Sie Funktionen mit Beschriftungen umwandeln. Bisher funktionierte diese Funktionalität nur in Funktionen ohne Beschriftung:func setX(x: Int) {}
(setX as (Int) -> Void)(5)
Die Standardwerte werden jedoch nicht gespeichert:func setPoint(x: Int, y: Int = 0) {}
(setPoint as (Int, Int) -> Void)(5, 1)
Dies gilt auch für Generika, sodass dieser Code nicht mehr gültig ist.typealias Point<T> = T
func set(x: Int) {}
(set as Point)(5)
(set as Point)(x: 5)
SR-11841 Die Filterfunktion (_ :) wird in verzögerten Sammlungen in der erwarteten Reihenfolge aufgerufen
Erstellen Sie eine faule Sammlung und rufen Sie die Zählmethode auf:let lazyArray = [0]
.lazy
.filter { _ in print("A"); return true }
.filter { _ in print("B"); return true }
_ = lazyArray.count
Vor dem Ergebnis des Anrufs war das Gegenteil: B A.SR-2790 Eine Reihe von Typinitialisierern der UnsafePointer / UnsafeBufferPointer-Familie geben jetzt eine Warnung aus
Die Einschränkung gilt für Zeichenfolgen, Arrays und Inout-Parameter, die außerhalb des Funktionsaufrufs nicht vorhanden sind.Erstellen Sie eine Struktur, die UnsafePointer während der Initialisierung als Parameter verwendet:struct Game {
let info: UnsafePointer<Int8>
}
func createGame() {
var i: Int8 = 0
_ = Game(info: .init(&i))
_ = Game(info: [1, 2])
_ = Game(info: "")
}
Es gab 9 Änderungen in dieser Version, aber sie führten definitiv neue Funktionen ein. Ich gehe davon aus, dass KeyPath als Funktion am häufigsten verwendet wird.Und wir freuen uns auf die nächste Version. Anscheinend wird Swift unter Windows unterstützt und es werden interessante Funktionen angezeigt , z. B. die Verwendung von self bei der Flucht vor Schließungen ohne Zugriff über self. * ( SE-0269 ) und die Funktionalität von Generika ( SE-0267 ) werden erweitert .Quelle