2016-04-30 8 views
9

Gemäß der Dokumentation von Apple benötigt Swift nicht unbedingt das Initialisieren des Initialisierers. In einem folgenden Codebeispiel erbt Bar initializer von Foo:Warum benötigt Swift das Überschreiben des designierten Initialisierers der generischen Superklasse?

class Foo { 
    let value: Int 
    init(value: Int = 5) { 
    self.value = value 
    } 
} 

class Bar: Foo { 
} 

Sobald wir einige generische in Foo wie class Foo<T> { Xcode bietet uns einen Fehler Initializer does not override a designated initializer from its superclass hinzufügen. Gibt es eine Dokumentation oder eine schnelle Evolutionsdiskussion, die erklärt, warum es passiert?


Aktualisierung. Es scheint, dass Generic keine Hauptursache für Override-Anforderungen ist. Hier ist eine Option, wie eine Klasse mit generisch zu definieren, die nicht außer Kraft gesetzt bestimmter Initialisierung erfordert:

protocol FooProtocol { 
    associatedtype T 
} 

class Foo<U>: FooProtocol { 
    typealias T = U 

    let value: Int 
    init(value: Int, otherValue: T) { 
     self.value = value 
     self.otherValue = otherValue 
    } 
} 

class Bar: Foo<Int> { 
} 

Allerdings gibt es eine weitere interessante Beobachtung des Verhaltens. Definieren initializer wie folgende Ursache Überschreibung Anforderung:

init(value: Int = 5) { 
    self.value = value 
} 

Die Komische Sache, die wie folgt in einer solche bezeichnet initializer Ursache diese Überschreibung Anforderung eines weiteren Parameter hinzufügen zu verschwinden:

init(value: Int = 5, otherValue: T) { 
    self.value = value 
} 

Update 2. Ich kann keine logische Erklärung für dieses Verhalten an dieser Stelle finden berichten ich es als Compiler Bug - https://bugs.swift.org/browse/SR-1375

+0

Ich habe mehr Tests durchgeführt und das Problem scheint _der Standardwert_ zu sein. Nehmen Sie die '= 5' aus Ihren Beispielen und _none_ von ihnen führen zu dem Compiler-Fehler. – matt

Antwort

1

ich einen Fehlerbericht tatsächlich für Erben von generischer Klasse gefüllt:

enter image description here

Es war zurück in November letzten Jahres und bekam noch keine Antwort, so ¯_ (ツ) _/¯

+0

Danke. Es ist definitiv hilfreich zu wissen, dass ich dieses Problem nicht allein habe. Inzwischen kann ich diese Nachricht nicht als Antwort zählen, da es weder Dokumentation noch schnelle Evolutionsdiskussion zu diesem Thema gibt. –

+0

Ich stimme zu: sehr interessant, aber das ist ein Kommentar, keine Antwort. – matt

1

Es ist eindeutig ein Bug. Darüber hinaus, obwohl der Fehler ausgelöst durch die Unterklasse eines generischen ist, ist seine proximate Ursache ist der Standardwert. Dies kompiliert just fine:

class Foo<T> { 
    let value: Int 
    init(value: Int) { 
     self.value = value 
    } 
} 

class Bar: Foo<String> { 
} 

Aber dies nicht:

class Foo<T> { 
    let value: Int 
    init(value: Int = 5) { 
     self.value = value 
    } 
} 

class Bar: Foo<String> { 
} 

Diese Art von willkürlicher Unterscheidung ohne Unterschied ein sicheres Anzeichen dafür, dass dies ein Compiler Fehler ist.

+0

Ich vermute, obwohl ich natürlich nicht beweisen kann, dass hinter den Kulissen, was sich für den Compiler als verwirrend erweist, dass das Aufrufen von 'init (Wert: Int = 5)' ohne einen 'Wert 'dasselbe wäre wie das Aufrufen von' init '. Ich weiß nicht, warum das im Falle eines Generikums verwirrend ist, aber das ist die Richtung, auf die Ihre Beispiele hinweisen. – matt

Verwandte Themen