Wenn eine generische Swift-Typ-Einschränkung ein Protokollname ist, kann ich verlangen, dass zwei Typen, die auf dieses Protokoll beschränkt sind, vom selben Typ sind. Zum Beispiel:Wie sagt man "selbe Klasse" in einem Swift generic
protocol Flier {}
struct Bird : Flier {}
struct Insect: Flier {}
func flockTwoTogether<T:Flier>(f1:T, f2:T) {}
Die Funktion flockTwoTogether
kann mit einem Vogel und einem Vogel oder ein Insekt und ein Insekt, aber nicht mit einem Vogel und ein Insekt genannt werden. Das ist die Einschränkung, die ich möchte. So weit, ist es gut.
Allerdings, wenn ich die gleiche Sache mit einem Klassennamen versuchen, funktioniert es nicht:
class Dog {}
class NoisyDog : Dog {}
class WellBehavedDog: Dog {}
func walkTwoTogether<T:Dog>(d1:T, d2:T) {}
Das Problem ist, dass ich walkTwoTogether
mit einem WellBehavedDog und einem NoisyDog aufrufen können. Das möchte ich verhindern.
Es gibt wirklich zwei Fragen hier:
Gibt es eine Möglichkeit zu sagen, dass
walkTwoTogether
kann nicht mit einem WellBehavedDog und einem NoisyDog genannt werden?Ist das ein Fehler? Ich frage, denn wenn ich kein generisches verwenden kann, um das zu sagen, ist es schwer zu verstehen, warum es für eine generische Constraint überhaupt nützlich ist, ein Klassenname zu sein, da wir das gleiche Ergebnis nur mit einer normalen Funktion erhalten könnten.
Das scheint wie erwartet Verhalten für mich? Sie haben das optionale Element vom Typ Hund eingeschränkt. Beide Unterklassen entsprechen diesem Typ, und nichts in der Deklaration beschränkt sie. Wenn es eine Möglichkeit gäbe, das zu tun, was Sie wollen, würde ich erwarten, dass es eine 'where'-Klausel benötigt, wie in' ', aber das wirft auch ein Error. –
cmyr
@cmyr Ja, natürlich habe ich das versucht. Deshalb habe ich gefragt, ob das, was ich tue, nicht ist, wie man es macht, ist es möglich, es zu tun. :) – matt
Alles funktioniert, wenn 'Dog' ein Protokoll ist.Generische Constraints können nicht für Nicht-Protokolltypen erzwungen werden. * (etwas Art Type Erasure) * – mattt