2016-10-09 5 views
1

Ich habe folgende Struktur:Compiler-Fehler für struct init in Swift

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

eine Person zu initialisieren, ich möchte es passieren, ein Wörterbuch, das den Namen und das Alter enthält, sowie Informationen die zur Berechnung Vermögen:

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 
    } 

Mit diesem Setup, erhalte ich zwei Compiler-Fehler:

  1. 'selbst' verwendet, bevor alle gespeicherten Objekte sind initia lized
  2. Rückkehr aus initializer ohne dass die gespeicherten Eigenschaften
  3. Initialisierung

Nach den Compiler Vorschläge, habe ich für jede Eigenschaft einen Standardwert, und verändert sie ein var sein:

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

// init ... 
} 

Und in der Tat, Die Compilerfehler sind weg.

Aber bin ich mit diesen Korrekturen auf dem richtigen Weg?

Antwort

1

Das Problem ist, dass in Ihrer init Funktion Sie könnte die Variablen initialisieren, aber Sie können nicht sicher sein, da die Bedingungen der if Aussagen false sein kann. Deshalb gibt der Compiler Ihnen die Fehler (auch weil Sie versuchen, self.assets in einer anderen Funktion aufzurufen, wenn die Variable möglicherweise noch nicht initialisiert wird, also müssen Sie mindestens diese in eine var ändern). Wenn Sie nicht sicher sein können, dass die Werte im info Wörterbuch gültig sind, sollten Sie Ihre Variablen in var ändern.

Jetzt haben Sie zwei Möglichkeiten:

  • Geben Sie Ihre Variablen einen Standardwert (wie Sie in Ihrem Beispiel tat)
  • Erklären Sie Ihre Variablen als Optionals (wie von @ Özgür vorgeschlagen).

Ihre Wahl hängt davon ab, was mehr Sinn macht. Wenn Ihre Standardwerte für Ihre Situation sinnvoll sind und Sie mit den Variablen mit diesen Werten arbeiten können, würde ich damit gehen.

Andernfalls sollten Sie mit der Optionals gehen.Optionals haben offensichtlich das Plus, dass Sie sie nicht initialisieren müssen, aber dann die Con ist, dass Sie sie implizit oder explizit später auspacken müssen, wenn Sie sie (mit ? oder !) verwenden möchten.

Wenn - welchem ​​Grund auch immer - Sie können sicher sein, dass die Werte in den info dict gültig sind - man könnte auch Ihre name und age als Konstanten (let) verlassen und nur explizit die Wörterbuchwerte auspacken, wenn Sie sie zuweisen :

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

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

Aber wie gesagt ich dies nur, wenn info["name"] und info["age"] gültige Werte enthalten würde funktionieren, sonst werden Sie eine Laufzeitausnahme erhalten. Daher sind die Optionen "Standardwert" oder "Optional" Ihre sicheren und sauberen Optionen, während dies der schnelle und schmutzige Weg ist.

+0

Got it. Und selbst wenn die Werte in Ordnung sind, könnte ich einen Laufzeitfehler bekommen, wenn ich einen Tippfehler mache: 'info [" naem "]'. Also werde ich einfach mit den Standardwerten oder den 'optionals' gehen, darüber muss ich nachdenken. – Koen

+0

Und eine Funktion von 'init' aufzurufen, ist ok, um einen Wert zu berechnen? – Koen

+1

Ja, solange die Variable, die Sie festlegen, als "Var" mit einem Standardwert oder als Optional deklariert ist. – Keiwan

1

Sie haben einen Compilerfehler, weil Ihre Variablen not inited sind, wenn Sie sie setzen (Sie definieren sie als inited). Deshalb für den zweiten Fall, wenn Sie init sie zu nil Werte, error ist weg. Für diese Bedingungen hat Swift optionals .Kann gleich null und ein Wert sein. Überprüfen Sie here. Sie können ? hinzufügen und das macht die Variable optional.

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

// init ... 
} 
+0

Allerdings ist der Name erforderlich (eine Person muss einen Namen haben), also kann es immer noch ein 'optional' sein? – Koen

+1

es geht nicht um das @ Koen, sollten Sie optionals sicher überprüfen –