2016-10-09 2 views
1

Я имею следующую структуру:ошибки компилятора для STRUCT инициализации в Swift

struct Person { 
    let name: String 
    let age: Int 
    let assets: Double 
} 

Для инициализации человека, я хотел бы передать его словарь, который содержит имя и возраст, а также информацию для расчета активы:

public init(info: [String : AnyObject]) { 
     if let name = info["name"] as? String { 
      self.name = name 
     } 

     if let age = info["age"] as? Int { 
      self.age = age 
     } 

     if let assets = info["assets"] as? [String : AnyObject] { 
      calculateAssets(assets: assets) 
     } 
    } 

    mutating func calculateAssets(assets: [String : AnyObject]) { 
     self.assets = 1+2+3.4 // really do this with info from the dictionary 
    } 

С помощью этой установки, я получаю две ошибки компилятора:

  1. «я», используемый перед всеми хранящимися свойствами являются Перво lized
  2. Возвращения из инициализаторе без инициализации всех сохраненных свойств

После предложения компилятора, я добавил значение по умолчанию для каждого свойства, и изменил их, чтобы быть var:

struct Person { 
    var name: String = "" 
    var age: Int = 0 
    var assets: Double = 0.0 

// init ... 
} 

И действительно, ошибки компилятора исчезли.

Но я нахожусь на правильном пути, сделав эти исправления?

ответ

1

Проблема заключается в том, что в вашей init функции вы может инициализировать переменные, но вы не можете быть уверены, так как условия в if заявления могут быть false. Вот почему компилятор дает вам ошибки (также потому, что вы пытаетесь вызвать self.assets в другой функции, когда переменная все еще не может быть инициализирована - так что вам, по крайней мере, нужно будет изменить ее на var).

Если вы не можете быть уверены, что значения в словаре info действительны, вы должны изменить свои переменные на var.

Теперь у вас есть два варианта:

  • Дайте ваши переменные значения в по умолчанию (как вы это делали в вашем примере)
  • объявить переменные Optionals (как было предложено @ Özgür).

Ваш выбор зависит от того, что имеет смысл. Если ваши значения по умолчанию имеют смысл для вашей ситуации, и вы можете работать с переменными, имеющими эти значения, тогда я бы пошел с этим.

В противном случае вы должны пойти с Optionals.Optionals, очевидно, имеют плюс, который вам не нужно инициализировать, но тогда вы должны будете неявно или явно разворачивать их позже, когда хотите их использовать (используя ? или !).

Если - по какой-либо причине - вы можете быть уверены в том, что значения в info Словаре действительны - вы можете также оставить свой name и age как константы (let) и только явно разворачивать словаря значения при назначении их :

self.name = info["name"] as! String 

self.age = info["age"] as! Int 

Но, как я сказал, что это будет работать только если info["name"] и info["age"] содержат допустимые значения, в противном случае вы получите исключение во время выполнения. Таким образом, варианты «по умолчанию» или «Необязательный» - это ваши безопасные и чистые варианты, тогда как это быстрый и грязный способ.

+0

Получил это. И даже если значения в порядке, я могу получить ошибку во время выполнения, если я создам опечатку: 'info [" naem "]'. Поэтому я просто перейду со значениями по умолчанию или 'optionals', мне нужно подумать об этом. – Koen

+0

И вызывать функцию из 'init' нормально для вычисления значения? – Koen

+1

Да, до тех пор, пока переменная, которую вы устанавливаете, объявляется как «var», либо по умолчанию, либо как необязательный. – Keiwan

1

У вас возникла ошибка компилятора, так как ваши переменные равны not inited, когда вы их установили (вы определяете их как inited). Вот почему для второго случая, когда вы init их до nil значений, error ушел. Для этих условий Swift имеет optionals. Может быть ноль и значение в одно и то же время. Проверьте here. Вы можете добавить ?, и это делает переменную optional.

struct Person { 
    var name: String? 
    var age: Int? 
    var assets: Double? 

// init ... 
} 
+0

Однако, имя обязательное (лицо должно иметь имя), так может ли оно быть «опциональным»? – Koen

+1

Это не о том, что @Koen, вы должны проверить опции для наверняка –

Смежные вопросы