2015-12-26 8 views
13

Ich arbeite an einem learn-swift playground und aktualisiere es auf Swift 2.0, während ich die Sprache lerne. Der folgende Code (was wahrscheinlich mit früheren Versionen von Swift gearbeitet) erzeugt nun zwei Fehler: „‚Selbst‘verwendet, bevor alle gespeicherten Eigenschaften initialisiert“ und „Constant‚self.capitalCity‘hat vor initialisiert“'self' verwendet, bevor alle gespeicherten Eigenschaften initialisiert werden

class Country 
{ 
    let name: String 
    let capitalCity: City! 

    init(name: String, capitalName: String) 
    { 
     self.name = name 
     self.capitalCity = City(name: capitalName, country: self) 
    } 
} 

class City 
{ 
    let name: String 
    unowned let country: Country 

    init(name: String, country: Country) 
    { 
     self.name = name 
     self.country = country 
    } 
} 

Lesung ein answer to a similar question Ich sehe, dass ich let capitalCity: City! zu var capitalCity: City! ändern kann und der Syntaxfehler behoben ist.

Mir ist klar, dass in diesem erfundenen Beispiel eine Hauptstadt des Landes, ändern kann, so dass wäre in Ordnung, aber was, wenn es einen Fall gab, wo der Wert wirklich eine Konstante ...

Gibt es eine Möglichkeit war, den Syntaxfehler beheben und die capitalCity konstant halten?

Antwort

9

In diesem Fall würde ich vorschlagen, Sie die Eigenschaft eine Variable zu machen, aber versteckt sie (machen es wie eine Konstante scheinen) durch eine berechnete Eigenschaft:

class Country { 
    let name: String 

    private var _capitalCity: City! 
    var capitalCity: City { 
     return _capitalCity 
    } 

    init(name: String, capitalName: String) { 
     self.name = name 
     self._capitalCity = City(name: capitalName, country: self) 
    } 
} 
+0

Dies ist eine großartige Antwort. Es kommt an die Schnittstelle, die ich wollte, obwohl die Erklärung von @matt fabelhaft war – Ultrasaurus

9

Gibt es eine Möglichkeit, den Syntaxfehler zu lösen, während capitalCity konstant gehalten wird?

Nicht die Art, wie Sie Dinge eingerichtet haben. Die Ursache des Problems ist eigentlich, dass Sie capitalCity setzen müssen, müssen Sie eine Stadt erstellen, deren countryself ist. Die ist die Verwendung von self, an der der Compiler beanstandet:

self.capitalCity = City(name: capitalName, country: self) 
                ^^^^ 

Da Sie Citys konfiguriert haben country als Konstante, Sie muss Versorgung dieses Wert, wenn Sie Ihre Stadt initialisieren. So hast du keinen Ausweg mehr; Sie müssen capitalCity ein Optional var machen, so dass es einige andere Anfangswert hat, der legal ist, nämlich nil. Ihre vorgeschlagene Lösung funktioniert tatsächlich wie folgt aus:

class Country 
{ 
    let name: String 
    var capitalCity: City! = nil // implicit or explicit 

    init(name: String, capitalName: String) 
    { 
     self.name = name 
     // end of initialization! 
     // name is set (to name), and capitalCity is set (to nil)... 
     // ... and so the compiler is satisfied; 
     // now, we _change_ capitalCity from nil to an actual City, 
     // and in doing that, we _are_ allowed to mention `self` 
     self.capitalCity = City(name: capitalName, country: self) 
    } 
} 
+0

Was ist mit Speicherleck? – user3441734

+0

@ user3441734 Das ist das Problem, das 'unowned' löst. – matt

+0

Sory, Sie haben nicht den Rest zur Verfügung gestellt .... mein Fehler! – user3441734

Verwandte Themen