web-dev-qa-db-ja.com

すべての保存されたプロパティが初期化される前に使用される「self」

私は learn-Swiftプレイグラウンド を使って作業しており、言語を習得するにつれてSwift 2.0にアップグレードしています。 )現在、2つのエラーが生成されます:「すべての保存されたプロパティが初期化される前に使用される「自己」」と「初期化される前に使用される定数「self.capitalCity」」

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
    }
}

同様の質問への回答 を読むことができますlet capitalCity: City!からvar capitalCity: City!および構文エラーが解決されます。

この不自然な例では、国の首都が変わる可能性があることを理解しているので、それは問題ないでしょうが、値が本当に一定である場合があったらどうなるでしょう...

CapitalCityを一定に保ちながら構文エラーを解決する方法はありますか?

22
Ultrasaurus

この場合、プロパティを変数にするが、計算されたプロパティを介してプロパティを非表示にする(定数のようにする)ことをお勧めします。

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)
    }
}
16
Qbyte

capitalCityを一定に保ちながら構文エラーを解決する方法はありますか?

物事を設定する方法ではありません。問題の原因は、実際にcapitalCityを設定するために、countryselfである市を作成する必要があることです。 そのは、コンパイラが反対しているselfの使用です。

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

Cityのcountryを定数として設定しているため、Cityを初期化するときにmustにこの値を指定します。したがって、出口はありません。 capitalCityをオプションのvarにして、正当な初期値other、つまりnilを持つようにする必要があります。実際に提案されたソリューションは次のように機能します。

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)
    }
}
14
matt