Erweiterung, mit der Wrapper, die sich selbst ausgeben, als Selbst eingegeben werden

matt

Entschuldigung für den seltsamen Titel. Hier ist eine Spielzeugskizze meines Codes:

extension UIControl {
    func makeHolder() -> ControlHolder {
        ControlHolder(control: self)
    }
}

struct ControlHolder {
    let control : UIControl
    init(control: UIControl) {
        self.control = control
    }
    func retrieve() -> UIControl {
        return self.control
    }
}

Ich gebe zu, dass dies eine Spielzeugreduktion ist, und ich mag es nicht, wenn Leute das tun, aber es veranschaulicht das syntaktische Problem perfekt, also lasst uns damit anfangen.

Okay, wir haben also eine Erweiterung für UIControl, eine Methode, die ein Wrapper-Objekt zurückgibt. Das Problem ist nun folgendes:

let holder = UISwitch().makeHolder()
let output = holder.retrieve()

Das Ergebnis outputwird offensichtlich als UIControl eingegeben. Aber das will ich nicht. Ich möchte, dass es als UISwitch eingegeben wird, da ich mit einem UISwitch begonnen habe. OK, das klingt nach einem Generikum. Das Problem ist, ich kann nicht herausfinden, wie man das generisch macht.

Ich denke, es ist einfach, ControlHolder zu einem Generikum zu machen:

struct ControlHolder<T:UIControl> {
    let control : T
    init(control: T) {
        self.control = control
    }
    func retrieve() -> T {
        return self.control
    }
}

Ich bin mir ziemlich sicher, dass ich diesen Teil richtig verstanden habe. Aber wie schreibe ich dann die Erweiterungsdeklaration so, dass diese generische in den tatsächlichen Typ des selfUIControl aufgelöst wird, auf dem makeHolderaufgerufen wird?

Ich habe versucht, ein Generikum in die Erweiterung einzuführen, wobei ich dem Compiler gehorchte, bis ich es zum Kompilieren bekam:

extension UIControl {
    func makeHolder<T>() -> ControlHolder<T> {
        ControlHolder<T>(control: self as! T)
    }
}

Aber das ist ziemlich albern und outputwird immer noch als UIControl eingegeben.

Natürlich kann ich einen weiteren Parameter hinzufügen, der den Typ explizit übergibt makeHolderund ihn somit auflöst:

extension UIControl {
    func makeHolder<T>(ofType: T.Type) -> ControlHolder<T> {
        ControlHolder<T>(control: self as! T)
    }
}

Wenn ich jetzt anrufe, gebe makeHolderich den Typ ein:

let holder = UISwitch().makeHolder(ofType: UISwitch.self)
let output = holder.retrieve()

Und jetzt wird natürlich outputals UISwitch getippt. Aber das ist idiotisch! Ich möchte, dass die Erweiterung nur weiß, dass der Typ UISwitch ist, da ich makeHoldereinen UISwitch aufrufe.

Ich habe das Gefühl, dass ich das alles falsch verstehe. Vielleicht kann mich jemand begradigen? Oder strebe ich etwas an, das einfach unmöglich ist?

Tyler

Der Trick dabei besteht darin, ein Protokoll, eine Erweiterung dieses Protokolls, zu definieren und die makeHolderMethode in diese Erweiterung einzufügen. Auf diese Weise können Sie Selfals generischen Typ für die Rückgabe verwenden ControlHolder.

Definieren Sie zuerst ein neues Protokoll (nennen wir es " HoldableControl") und fordern Sie, dass Konformere UIControls sein müssen. Es sind keine weiteren Anforderungen erforderlich, da wir nur die makeHolderFunktion einer Erweiterung hinzufügen möchten.

protocol HoldableControl: UIControl {}

Fügen Sie dann eine Erweiterung von hinzu HoldableControlund definieren Sie makeHoldersie, wobei Sie zurückkehren ControlHolder<Self>. Wir dürfen Selfhier verwenden, da dies in Protokollerweiterungen im Gegensatz zu einer Erweiterung auf zulässig ist UIControl.

extension HoldableControl {
    func makeHolder() -> ControlHolder<Self> {
        ControlHolder(control: self)
    }
}

Dann müssen wir uns nur noch UIControlan dieses Protokoll halten:

extension UIControl: HoldableControl {}

Und machen Sie Ihr ControlHolderGenerikum, wie Sie es bereits getan haben:

struct ControlHolder<T: UIControl> {
    let control: T
    
    init(control: T) {
        self.control = control
    }
    
    func retrieve() -> T {
        control
    }
}

Und jetzt wird es funktionieren:

let holder = UISwitch().makeHolder() // type is ControlHolder<UISwitch>
let output = holder.retrieve()       // type is UISwitch

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Lassen Sie g ++ eine Warnung ausgeben, wenn Sie die Variable mit sich selbst vergleichen

Löschen Sie Elemente der Liste, die vor einem Element und sich selbst mit R angezeigt werden

String-Erweiterung, die sich schnell selbst ändert

Schleife, die Werte mit sich selbst multipliziert

Schleife, die Werte mit sich selbst multipliziert

Die Ausgabe der Konsolen-App kann in PowerShell nicht in sich selbst weitergeleitet werden

Kann die Nullstellung des Speichers durch Xoring von Daten mit sich selbst in C optimiert werden?

"Kann sich selbst nicht als Unteransicht hinzufügen" Absturz (mit Beispielcode), wenn sich die Ansicht nicht selbst zu ihrer Unteransicht hinzufügt

Problem mit der Kollision der Schlange mit sich selbst (Schlangenspiel)

Vorlagenklasse, die sich selbst als Argument verwendet. C ++

Kraftunterklasse mit sich selbst zu überschreiben Methode als Parameter

Endlose Schleife mit, wenn Sie sich selbst als Delegierter übergeben

So verbinden Sie die Tabelle mit sich selbst, wenn sie auf sich selbst verweist

Die Funktion max () in R hat einen Wert zurückgegeben, der nicht mit sich selbst übereinstimmt

Funktion, die sich selbst ausführt, ohne aufgerufen zu werden

Wie kann verhindert werden, dass sich die Datei selbst überschreibt?

Rails SQL finden Modelle, die sich auf sich selbst beziehen und deren Attributdifferenz größer als der Schwellenwert ist

Wie zeige ich die fehlenden Monate im Mongo-Aggregat als sich selbst mit 0 als Wert an?

Erstellen Sie eine Tabelle mit einem Kopf, der breiter als die Tabelle selbst ist

Programme, die sich selbst reproduzieren

Verhalten der Bewegungszuweisung an sich selbst

Konstruktor, der sich selbst aufruft

Schnelle Wache mit sich selbst

sich selbst mit Pandas verbinden

Struktur mit sich selbst deklarieren?

Wie löschen sich die Datensätze der Sitzungstabelle selbst?

die Summe der Teiler (außer sich selbst)

Lisp-Variable, die sich selbst in der Definition verwendet

SQL Server - Multiplizieren Sie die Werte mit sich selbst

TOP Liste

  1. 1

    So legen Sie mit dem Interface Builder unterschiedliche führende Speicherplätze für unterschiedliche Geräte fest

  2. 2

    Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

  3. 3

    Wie kann ich in SCSS mehrere Klassen zu einer einzigen kombinieren?

  4. 4

    Eclipse Oxygen - Projekte verschwinden

  5. 5

    Wie konvertiert man einen Datenrahmen im langen Format in eine Liste mit einem geeigneten Format?

  6. 6

    Wie kann ich den Kaskadenmodus global einstellen?

  7. 7

    Wie erstelle ich einen neuen übergeordneten Knoten außerhalb der .ref (/ path) in der Firebase-Echtzeitdatenbank mithilfe von Cloud-Funktionen (Typescript)?

  8. 8

    So erhalten Sie eine gleichmäßige Höhe für alle Eingabefelder

  9. 9

    Python: Spalten mit demselben Namen zusammenführen, wobei der Mindestwert beibehalten wird

  10. 10

    Speichern Sie ein MPAndroidChart-Diagramm in einem Bild, ohne es in einer Aktivität anzuzeigen

  11. 11

    Gruppieren Sie Datenrahmenspalten nach ihrem Datum (die Spaltentitel enthalten) und fassen Sie die Instanzen von Einsen und Nullen in R . zusammen

  12. 12

    ElasticSearch BulkShardRequest ist aufgrund von org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor fehlgeschlagen

  13. 13

    Tic Tac Toe-Spiel im React-Reset-Button funktioniert nicht

  14. 14

    Tomcat - Leiten Sie den alten Kontextstamm zum neuen Kontextstamm um

  15. 15

    Wie wählt man Unterschiede mit drei Tabellen aus?

  16. 16

    Ärgerliches Problem mit yaml, das ich nicht lösen kann

  17. 17

    Wie kann ich meine Tabelle abfragen, um sie in mySQL nach 2 Feldern zu gruppieren?

  18. 18

    So berechnen Sie die Verfügbarkeit von Anwendungen (SLA)

  19. 19

    Fügen Sie eine weitere Schaltfläche zu gwt Suggest Box hinzu

  20. 20

    Modbus Python Schneider PM5300

  21. 21

    Wie kann eine gleichmäßige Lastverteilung in ElasticSearch mit Indizes mit unterschiedlicher Anzahl von Shards erreicht werden?

heißlabel

Archiv