"self" используется до того, как все сохраненные свойства будут инициализированы
Я работаю над обучаемой быстрой площадкой и обновляя ее до Swift 2.0, когда изучаю язык. Следующий код (который, вероятно, работал с предыдущими версиями Swift) теперь генерирует две ошибки: "self" используется до того, как все сохраненные свойства инициализируются "и" Constant "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?
Ответы
Ответ 1
В этом случае я предлагаю вам сделать свойство переменной, но скрывать его (сделать его похожим на константу) через вычисленное свойство:
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)
}
}
Ответ 2
Есть ли способ разрешить синтаксическую ошибку, сохраняя capitalCity
константу?
Не так, как у вас есть вещи. Источником проблемы является то, что для установки capitalCity
вам нужно создать Город, country
которого self
. Это использование self
, против которого компилятор возражает:
self.capitalCity = City(name: capitalName, country: self)
^^^^
Поскольку вы настроили City country
как константу, вы должны указать это значение при инициализации своего города. Таким образом, у вас нет выхода; вы должны сделать capitalCity
необязательным var
, чтобы иметь другое начальное значение, которое является законным, а именно 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)
}
}