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

heißlabel

Archiv