Thanks everyone! I found the following snippet in another answer, which I like:
let d = zoo["Barky"] ?? {
let d = Dog()
zoo["Barky"] = d
return d
}()
Since I needed that idiom in quite many place, I also went with an extension to 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() })
Then I found that the subscript
operator could be overloaded as well:
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() }]