[Swift] Aufzählungstyp für gemeinsam genutzte Typen

1. Zuallererst


Ich habe das letzte Mal den Aufzählungstyp erklärt, aber dieses Mal werde ich den Aufzählungstyp des gemeinsam genutzten Typs erläutern, wie ich Ihnen zuvor gesagt habe.

Es ist sehr eng mit dem vorherigen Artikel verwandt. Wenn Sie es also noch nicht gelesen haben, lesen Sie bitte auch diesen Artikel. (https://qiita.com/0901_yasyun/items/a87c49438db68241778b)

2. Übersicht über den gemeinsam genutzten Aufzählungstyp


Ein "Shared Type Enumeration Type" ist ein Typ, der sowohl einen einfachen "Enumeration Type" haben kann, der keinen "substantiellen Typ" angibt, als auch eine Struktur aus mehreren verschiedenen "Tapples". Ziel dieses Typs ist es, mehrere verschiedene Datentypen zusammen mit einem gemeinsamen Konzept verarbeiten zu können.

Im Folgenden finden Sie zunächst eine Übersicht über die Definition des Aufzählungstyps "Shared Type". Es ist ein einfacher Fallname vom Typ "Aufzählungstyp", gefolgt von einer "tapple" -Deklaration.

Name des Aufzählungstyps{
case Fallname Tupple-Typdeklaration
case Fallname Tupple-Typdeklaration
    ... ...

Das Folgende ist ein konkretes Definitionsbeispiel. In diesem Beispiel wird die zum Erstellen einer Webseite usw. verwendete Farbe durch den Farbnamen der Zeichenfolge, den Farbcode durch Hexadezimalzahl usw. angegeben. Da der Zweck der Angabe der Farbe jedoch in allen Formaten gleich ist, ist dies der Fall Ziehen Sie in Betracht, mit einem Datentyp auszudrücken.

python


enum WebColor {
    case name(String)       //Farbname
    case code(String)       //Sechseck-Farbcode
    case white, black, red  //Häufig verwendete Farben
}

Mit dieser Definition können Sie verschiedene Instanzen erstellen.

python


let background = WebColor.name("indigo")   //Indigo Blau
let turquoise: WebColor = .code("#40E0D0") //Türkis
let textColor = WebColor = .black          //schwarz

** Informationen, die in einer Tapple-Typ-Struktur ** beschrieben sind, werden im Folgenden als "zusätzliche Informationen" oder "Nutzlast" bezeichnet. Sie können keinen "wesentlichen Typ" in die Definition eines "gemeinsamen Typs" schreiben. Der "Werttyp" und der "Aufzählungstyp für gemeinsam genutzte Typen" müssen als getrennt beschrieben werden.

Im vorherigen einfachen Aufzählungstyp und Aufzählungstyp für Werttypen war es möglich, Elemente zu vergleichen. Im Fall des Aufzählungstyps für gemeinsam genutzte Typen können Sie den Operator == entweder selbst oder definieren Solange das Protokoll Equtable nicht übernommen wird, kann ** nicht miteinander verglichen werden **.

python


if turquoise == WebColor.code("#40E0D0")  //Error. Kann nicht vergleichen

Hier ist ein etwas komplizierteres Beispiel. Im folgenden Beispiel gehen wir davon aus, dass eine der verschiedenen Arten von Tickets und Prepaid-Karten, die in der städtischen U-Bahn verkauft werden, von automatischen Fahrkartenschaltern verarbeitet werden kann, und wir haben die Arten von Tickets und Karten als "Aufzählungstyp" definiert.

python


enum Ticket {
Fallkarte(Int, Bool,Coupon:Bool)  //Normales Ticket: Preis, Kind, Gutschein
Fallkarte(Int, Bool)             //Prepaid-Karte: Guthaben, Zwerg
Fall Keiro Bus//Keiro Bus
}

Sie können auch Schlüsselwörter zu Elementen mit "Taple" in den im Fall beschriebenen Klammern hinzufügen. Verwenden Sie die "switch-Anweisung", um die Verarbeitung für einen solchen "Aufzählungstyp" zu trennen. Wenn Sie Konstanten und Variablen Werte zuweisen können und keine "zusätzlichen Informationen" verwenden, können Sie auch nicht ** nach Klammern ** wie die ".card" unten ** schreiben.

Im Folgenden wird die Beschreibung des strukturellen Zustands ** nach dem Fall ** als "Fallmuster" bezeichnet. Die Bedingung kann auch so geschrieben werden, dass sie mit "taple" identisch ist. Überprüfen Sie das folgende Beispiel.

python


switch t {
case let .Fahrkarte(fare, flag, _):
    print("Normales Ticket: \(fare) " + (flag ? "Kind" : "aufgewachsen"))
case .Keiro Bus:
    print("Keiro Bus")
case .Karte(let r, true) where r < 110:  //Mindestpreis für Kinder
    print("Karte:Unzureichende Mittel")
case .Karte(let r, false) where r < 230: //Mindestpreis für Erwachsene
    print("Karte:Unzureichende Mittel")
case .Karte:
    print("Karte")

Ähnlich wie bei der Verwendung von "taple" in einer switch-Anweisung können Sie let verwenden, um innerhalb () oder außerhalb zu platzieren, um einer Konstante "zusätzliche Informationen" zuzuweisen.

python


case let .Fahrkarte(fare, flag, _):     //Oder
case .Fahrkarte(let fare, let flag, _):

Für Tupel mit Schlüsselwörtern müssen Sie kein Etikett in das Fallmuster schreiben, aber Sie können. Wenn Sie mit let verwenden, müssen Sie vorsichtig sein, wo Sie let schreiben.

python


case let .Fahrkarte(fare, _,Coupon: flag):     //Oder
case .Fahrkarte(let fare, _,Coupon: let flag):

3. Über die if-case-Anweisung


Die switch-Anweisung war hilfreich, um herauszufinden, welche der mehreren Bedingungen das angegebene Taple erfüllt **. Es kann jedoch vorkommen, dass Sie ** prüfen möchten, ob nur eine bestimmte Bedingung erfüllt ist **.

Angenommen, Sie möchten nur herausfinden, ob es sich bei der im vorherigen Beispiel verwendeten Tickettypvariablen p um eine Prepaid-Karte handelt. Die if-Anweisung kann jedoch nicht wie folgt beschrieben werden.

python


if p == .Karte{              //Error. Diese Beschreibung ist nicht möglich
    print("Prepaid Karte")
}

Die switch-Anweisung kann wie folgt geschrieben werden, ist jedoch etwas problematisch, da Sie die Standardklausel schreiben müssen, von der Sie wissen, dass Sie sie nicht verwenden werden.

python


switch p {
case .Karte: print("プリペイドKarte")
default: break
}

Daher gibt es eine Syntax, die auch in solchen Fällen leicht geschrieben werden kann. Das obige Beispiel kann wie folgt geschrieben werden: Diese Syntax wird manchmal als "if-case-Anweisung" bezeichnet.

python


if case .Karte= p {
    print("Prepaid Karte")

Beschreiben Sie für die Bedingung zuerst das "Fallmuster" und setzen Sie dann den Zielausdruck als "=". Ob der Ausdruck mit dem "Fallmuster" übereinstimmt, wird auf die gleiche Weise wie in der switch-Anweisung verarbeitet. Im Gegensatz zur switch-Anweisung ist die zusätzliche Bedingung keine where-Klausel, sondern wird durch ein Komma "," getrennt und befolgt.

Diese Notation ist dieselbe wie unter Schreiben von Bedingungen für if, while- und guard-Anweisungen beschrieben, und Sie können allgemeine Ausdrücke, optionale Bindungssyntax usw. durch Kommas getrennt schreiben.

wenn Fallmuster=Formel,Bedingungen{.....}

Im folgenden Beispiel wird geprüft, ob der Inhalt der Variablen t eine Prepaid-Karte mit einem Guthaben von 1200 Yen oder mehr ist.

python


if case .Karte(let y, _) = t, y >= 1200 { .....

Als etwas komplizierteres Beispiel schreiben wir eine Bedingung, die ein Ticket-Typ-Element aus einer Instanz eines Wörterbuchs entnimmt und prüft, ob die Informationen mit dem Muster übereinstimmen.

python


let tickets:[String:Ticket] = [ "Shikura" : .Fahrkarte(260, false,Coupon: true), 
               "Sasaki" : .Fahrkarte(220, false,Coupon:false)]
let name = "Sasaki"
if let t = tickets[name], case .Fahrkarte(220, _, _) = t {
    print("220 Yen Ticket")
}

In diesem Beispiel sind die aus dem Wörterbuch erhaltenen Informationen "optionaler Typ". Rufen Sie also zuerst eine Instanz des Ticket-Typs in der Konstante t mit "optionaler Bindungssyntax" ab. Im Fall von Null ist die if-Bedingung dort nicht erfüllt, aber wenn sie nicht null ist, prüfen Sie, ob die Konstante t ein Ticket von 220 Yen ist.

Die obige if-Anweisung kann auch mit "?" Wie folgt beschrieben werden.

python


if case .Fahrkarte(220, _, _)? = tickets[name] {
    print("220 Yen Ticket")
}

4. Verwenden Sie das Fallmuster in der for-in-Anweisung


Sie können auch das Fallmuster in der for-in-Anweisung verwenden. Ähnlich wie bei der bisher erläuterten for-in-Anweisung wird ein Ausdruck, der dem "Sequenzprotokoll" entspricht, wie z. B. ein Array, neben in platziert, und Instanzen werden nacheinander abgerufen.

In diesem Format wird der Codeblock nur ausgeführt, wenn die abgerufene Instanz dem folgenden Muster des Falls entspricht. Sie können auch eine where-Klausel hinzufügen, wenn Sie weitere Bedingungen für die Ausführung schreiben müssen.

für Fallmuster im Ausdruck wo Ausdruck{
Satz... ...
}

Gehen Sie wie folgt vor, um die Instanzen nacheinander aus den Array-Durchläufen mit Ticket-Typ-Elementen abzurufen und die Informationen von Tickets anzuzeigen, die höher als 220 Yen sind.

python


for case let .Fahrkarte(fare. child, coupon) in passes where fare > 220 {
    var k = coupon ? "Coupon" : "Normales Ticket"
    if child { k += "(Kind)" }
    print(k, "\(fare)Kreis")
}

Diese Aussage ist die gleiche wie das Schreiben:

python


for t in passes {
    switch t {
    case let .Fahrkarte(fare, child, coupon):
        if fare > 220 {
            var k = coupon ? "Coupon" : "Normales Ticket"
            if child { k += "(Kind)" }
            print(k, "\(fare)Kreis")
        }
    default: break
    }
}

Sie können das "?" Verwenden, das für den "optionalen Typ" in dieser Syntax gilt, um Datenzeichenfolgen zu verarbeiten, die den "optionalen Typ" enthalten. Sie können auch var anstelle von let verwenden.

5. Rekursiver Aufzählungstyp


Möglicherweise möchten Sie sich als Element in einem Taple mit einem "gemeinsamen Aufzählungstyp" angeben. Betrachten Sie beispielsweise den folgenden Fall.

python


enum Nachricht{
Falldokument(String, String)     //Von, Dokument
Falldaten(String, [Int8])   //Von, Datenspalte
Fallübertragung(String,Botschaft)  //Von, Nachricht
}

Diese Datendeklaration scheint nicht falsch zu sein, aber Swift kann damit nicht umgehen.

In Swift sind "Aufzählungstyp" "Werttyp" -Daten. Um dies intuitiv zu erklären, werden Ladeinformationen direkt nebeneinander in dem Speicherort gespeichert, der die "Aufzählungstyp" -Daten darstellt. Wie oben erwähnt, einschließlich sich selbst, dh ** können rekursive Datenstrukturen zur Kompilierungszeit nicht bestimmen, wie viel Speicher zum Speichern der Daten benötigt wird **.

Andererseits sind "Referenztyp" -Daten Informationen zum indirekten Referenzieren einer Entität, die irgendwo im Speicher vorhanden ist, so dass es kein Problem mit dem Speicher gibt.

Es gibt jedoch viele Situationen, in denen es zweckmäßig ist, den "rekursiven Aufzählungstyp" zu verwenden. Wenn sich der "Aufzählungstyp" ** in Swift in den zusätzlichen Informationen enthält, schreiben Sie das Schlüsselwort indirekt vor den entsprechenden Fall. **. Dies wird als "indirekte Spezifikation" bezeichnet. "indirekt", dh indirekt, bedeutet, dass nur dieser Teil indirekt wie ein Zeiger referenziert wird.

Die aktuelle Geschichte wird im folgenden Beispiel gezeigt. Das "CustomStringConvertible" -Protokoll wird übernommen, damit es per Druck angezeigt werden kann.

python


enum Nachricht: CustomStringConvertible {
Falldokument(String, String)              //Von, Dokument
Falldaten(String, [Int8])            //Von, Datenspalte
indirekte Fallübertragung(String,Botschaft)  //Von, Nachricht
    
    ver description: String {
        switch self {
        case let .Unterlagen(from, str): return from + "(" + str + ")"
        case let .Daten(from, _): return from + "[Daten]"
        case let .Transfer(from, msg): return from + "←\(msg)"
        }
    }
}

Ein Ausführungsbeispiel ist unten gezeigt.

python


let m1 =Botschaft.Unterlagen("Ito", "Nimm den Rest")
let m2 =Botschaft.Transfer("Shiraishi", m1)
let m3 =Botschaft.Transfer("Yamada", m2)
print(m3)   // "Yamada ← Shiraishi ← Ito(Nimm den Rest)"Ausgabe

Wenn Sie einige rekursive "Fallmuster" haben, können Sie "indirekt" vor die Aufzählung setzen, um die gesamte indirekte Spezifikation zu erstellen.

6. Fazit


Dieses Mal habe ich einen Artikel über gemeinsam genutzte Aufzählungstypen geschrieben, aber ich werde nicht erklären, wie mit Protokollen und optionalen Typen umgegangen wird, da der Artikel etwas lang sein wird. Ab nächster Woche werde ich über Klassen und so weiter erklären. Vielen Dank an alle, die bisher gelesen haben.

Recommended Posts

[Swift] Aufzählungstyp für gemeinsam genutzte Typen
Aufzählung (Aufzählungstyp)
[Java] Aufzählungstyp
[Swift] Über den Aufzählungstyp
[Swift] Zusammenfassung über den Bool-Typ
Großartiger Kommentar vom Typ Swift-Zeiger
[Java] Express-Aufzählungstyp ohne Verwendung des Aufzählungstyps (Aufzählung)
[Swift] Konvertiert eine Ganzzahl vom Typ UInt64 in [UInt8]
Versuchen Sie, Klassen nach Aufzählungstyp zu sortieren