2017-06-18 5 views
1

J'utilise let pour déballer un dictionnaire facultatif, mais je trouve qu'il est difficile de gérer le cas d'ailleurs.Swift: Développer facultatif sinon créer une nouvelle instance

if let d : Dog = zoo["Barky"] { 
    d.bark() 
    } else { 
    // Create missing Dog 
    let d : Dog = Dog.init() 
    zoo["Barky"] = d 
    d.bark() 
    } 

Existe-t-il un moyen de rendre ceci plus concis/élégant?

  • Comment tirer sur l'appel en double à aboyer()
  • Comment éviter la définition en double let.
+0

connexes: [le dictionnaire standard Swift ont un rendez-vous ou régler la fonction?] (https://stackoverflow.com/questions/41 001705/does-the-swift-standard-dictionary-have-a-get-or-set-function) –

Répondre

0

Un peu plus courte autre:

var d: Dog!= zoo["Barky"] 
if d == nil { 
    d = Dog() 
    zoo["Barky"] = d 
} 
d.bark() 

ou (si vous ne me dérange pas de vérifier votre dictionnaire deux fois):

if zoo["Barky"] == nil { 
    zoo["Barky"] = Dog() 
} 
zoo["Barky"]!.bark() 
1

Vous pouvez utiliser le ?? opérateur de cette façon:

let d = zoo["Barky"] ?? Dog.init() 
zoo["Barky"] = d 
d.bark() 

Swift 4 dictionnaires peuvent avoir des valeurs par défaut. Exemple:

let d = zoo["Barky", default: Dog.init()] 
+0

Je le pensais moi-même, mais malheureusement il a encore besoin de stocker le nouveau 'Dog' dans le dictionnaire' zoo'. –

+0

La seule façon rapide qui me vient à l'esprit est d'ajouter l'objet au dictionnaire la ligne après. Malheureusement, il n'y a pas plusieurs affectations dans Swift. –

+0

Je ne pense pas que lancer un nouveau dictionnaire soit une bonne idée, car si le dic est un peu plus compliqué, il sera plus difficile d'utiliser votre réponse. –

0

vous pouvez le faire dans deux lignes de code. :)

let d: Dog = zoo["Barky"] ?? Dog() 
zoo["Barky"] = d 
d.bark() 
+1

Cela n'ajoute pas le nouveau chien au dictionnaire. – Keiwan

+0

vous pouvez ajouter cette ligne 'zoo [" Barky "] = d' facilement, laissez-moi éditer ma réponse –

+0

Maintenant vous insérez inutilement 'd' dans le dictionnaire même si c'est la même valeur qui existe déjà dans le dictionnaire - et cela va être le cas à chaque fois sauf pour la première fois. – Keiwan

1

Que pensez-vous de cela?

if zoo["Barky"] == nil { 
    zoo["Barky"] = Dog() 
} 

zoo["Barky"]?.bark() 
0

Merci à tous! J'ai trouvé l'extrait suivant dans une autre réponse que j'aime:

let d = zoo["Barky"] ?? { 
    let d = Dog() 
    zoo["Barky"] = d 
    return d 
}() 

Depuis que je devais cet idiome en fait beaucoup place, Je suis aussi allé avec une extension Dictionary:

extension Dictionary { 

    mutating func get_or_set(_ key: Key, defaultValue:() -> Value) -> Value { 
     if let value = self[key] { 
      return value 
     } else { 
      let value = defaultValue() 
      self[key] = value 
      return value 
     } 
    } 
} 

let d = zoo.get_or_set("Barky", defaultValue: { Dog() }) 

Je trouve que l'opérateur subscript pourrait être surchargé ainsi:

extension Dictionary {  
    subscript(key: Key, defaultFunc defaultFunc:() -> Value) -> Value { 
     mutating get { 
      return self[key] ?? { 
       let value = defaultFunc() 
       self[key] = value 
       return value 
      }() 
     } 
    } 
} 

var d = zoo["Barky", defaultFunc: { Dog.init() }]