我已经习惯使用Python的默认模式的模式是一个字典,如果没有明确设置给定键的值,则返回默认值.试图在Swift中这样做有点冗长.
var dict = Dictionary<String, Array<Int>>()
let key = "foo"
var value: Array<Int>! = dict[key]
if value == nil {
value = Array<Int>()
dict[key] = value
}
Run Code Online (Sandbox Code Playgroud)
我意识到我可以创建一个这样做的类,但是实际的Dictionary必须通过属性访问才能使用任何其他正常的Dictionary方法
class DefaultDictionary<A: Hashable, B> {
let defaultFunc: () -> B
var dict = Dictionary<A, B>()
init(defaultFunc: () -> B) {
self.defaultFunc = defaultFunc
}
subscript(key: A) -> B {
get {
var value: B! = dict[key]
if value == nil {
value = defaultFunc()
dict[key] = value
}
return value
}
set {
dict[key] = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
这有更好的模式吗?
Two*_*aws 16
这在Swift 4中发生了变化,现在有一种方法可以读取键值或者如果键不存在则提供默认值.例如:
let person = ["name": "Taylor", "city": "Nashville"]
let name = person["name", default: "Anonymous"]
Run Code Online (Sandbox Code Playgroud)
这在修改字典值时特别有用,因为您可以编写如下代码:
var favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"]
var favoriteCounts = [String: Int]()
for show in favoriteTVShows {
favoriteCounts[show, default: 0] += 1
}
Run Code Online (Sandbox Code Playgroud)
我在文章中介绍了Swift 4中的新功能.
使用Swift 2可以实现类似于python版本的扩展Dictionary:
// Values which can provide a default instance
protocol Initializable {
init()
}
extension Dictionary where Value: Initializable {
// using key as external name to make it unambiguous from the standard subscript
subscript(key key: Key) -> Value {
mutating get { return self[key, or: Value()] }
set { self[key] = newValue }
}
}
// this can also be used in Swift 1.x
extension Dictionary {
subscript(key: Key, or def: Value) -> Value {
mutating get {
return self[key] ?? {
// assign default value if self[key] is nil
self[key] = def
return def
}()
}
set { self[key] = newValue }
}
}
Run Code Online (Sandbox Code Playgroud)
??用于类之后的闭包,因为它们不传播它们的值变异(仅"指针变异";引用类型).
字典必须是mutable(var)才能使用这些下标:
// Make Int Initializable. Int() == 0
extension Int: Initializable {}
var dict = [Int: Int]()
dict[1, or: 0]++
dict[key: 2]++
// if Value is not Initializable
var dict = [Int: Double]()
dict[1, or: 0.0]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3772 次 |
| 最近记录: |