2016-04-22 2 views
-3

Edit: fertig, Duplikat von Why doesn't this obvious infinite recursion give a compiler warning? Ich glaubte, dass angesichts der vielen cleveren Warnungen Swift und des designierten Initialisierungssystems, dass es vernünftig war, eine Warnung zu erwarten, aber dies ist falsch, wie oben erläutert.Swift Initialiser Fehler?

Ich fand dieses interessante Beispiel, indem ich mit Protokollerweiterungen herumspielte, dann erkannte ich, dass es auch Struk- turen vermasselt.

struct WhatThe { 
let a = 1 
init(value: Int) { 
    self.init() 
} 

init() { 
    self.init(0) 
} 
} 

print(WhatThe().a) //nothing is printed and the CPU goes nuts. 

Dies ist ein Fehler, nicht wahr? Ich verstehe, dass dies eine Endlosschleife ist, ich bin wirklich überrascht, dass Apple das erlaubt hat. Dieser Code hat keine Warnungen und baut sich gut, Playground läuft sogar. Ich fühle mich wie diese Art von Sache war ein offensichtliches Problem in der Sprache loswerden. Es ist in Klassen richtig? - denn das sind beide Convenience Initialisierer?

+0

Dies ist kein Fehler, sondern der Spezialfall von Endlosschleifen, der _infinite recursion_ ist, was ein ziemlich üblicher _developer error_ ist, der in keiner Weise spezifisch mit Swift-Initialisierern verwandt ist. Ein noch einfacheres Initialisierungsbeispiel ist z.B. 'struct Foo {init() {self.init()}}', wobei (wie in obigem Beispiel) eine unendliche Rekursion aufgerufen wird, wenn eine 'Foo'-Instanz initialisiert wird; leicht vergleichbar mit dem bekannteren unendlichen Rekursionsbeispiel einer rekursiven Funktion, die sich selbst aufruft, etwa 'func foo() {foo()}', wobei beim Aufruf eine unendliche Rekursion aufgerufen wird; 'foo()'. – dfri

+1

Da die Wurzel dieser Frage nicht wirklich Swift-Sprache-spezifisch ist, schlage ich vor, dass sie als Duplikat von z.B. [Unendliche Rekursion in C] (http://stackoverflow.com/questions/18227093/infinite-recursion-in-c) oder z.B. [Warum gibt diese offensichtliche unendliche Rekursion keine Compilerwarnung?] (Http://stackoverflow.com/questions/8762234/why-doesnt-this-obvious-infinite-recursion-give-a-compiler-warning) (this Letzteres jedoch geschlossen, enthält immer noch eine gute Antwort auf Compiler-Warnungen und warum diese nicht unendliche Rekursion fangen können). – dfri

+0

Danke euch beiden, das ist es gelöst. Ich habe gewählt, um es als ein Duplikat von http://stackoverflow.com/questions/8762234/why-doesnt-this-obvious-infinite-recursion-give-a-compiler-warning zu schließen, obwohl der ehemalige http: // stackoverflow. com/questions/18227093/Infinite-Rekursion-in-c ist nicht wirklich die gleiche Frage in meinem Kopf. –

Antwort

2

Dies ist nur ein Fall von einer Endlos-Schleife, Ihre init() Funktion aufruft init(value:), die wiederum init() wieder ruft, und so weiter, so dass es nie endet. Nun, es wird enden, wenn der Stapel überläuft und abstürzen wird.

+0

Entschuldigung, ich hätte klarer sein sollen. Ich weiß das (es hat ein paar Sekunden gedauert), aber ich bin überrascht, dass das kompiliert werden darf! –

+2

Um diese Schleife zu bemerken, müsste der Compiler Ihren Code ausführen, was nicht der Job des Compilers ist. Beide Funktionen sind gültig, deshalb kompiliert es. – EmilioPelaez

+0

Das Problem besteht nicht darin, dass es eine Schleife gibt, sondern dass designierte Initialisierer andere designierte Initialisierer aufrufen. Noch seltsamer, wenn "let a: Int" verwendet wird, so dass "a" keinen Standardwert hat, dann kompiliert der Code * immer noch, obwohl auf "self" verwiesen wird, bevor "a" zugewiesen wird. – BallpointBen