创建 Swift 词典子类?
Create a Swift Dictionary subclass?
我可以将 Swift
Dictionary
子类化,以便我可以将我的自定义 Dictionary
传递给需要普通 Dictionary
的方法吗?
编辑
不,swift中的字典和数组是结构体,不支持继承。 "personalize" 字典的唯一方法是使用扩展。
Swift 字典是结构,而不是 类,因此它们不能被子类化。理想情况下,您正在使用的方法将被声明为采用适当约束的通用 CollectionType(或 ExtensibleCollectionType 或 SequenceType,视情况而定),而不是具体的字典。
如果出于某种原因这对您不起作用,您可以改为子类化 NSDictionary。
(编辑)正如 Antonio 指出的那样,您可以执行扩展 Dictionary { … } 以向 Dictionary 结构添加内容,这在某些情况下可以取代子类化。
虽然我同意这里的大部分评论(你不能子class一个Struct
,设计它不是class),您可能会通过符合 CollectionType
的自定义 Struct
(现在在 Swift 3.0 中重命名为 Collection
)获得您想要的结果:
struct YourCustomDictionary<Key : Hashable, Value>: Collection {
private var elements = Dictionary<Key, Value>()
private var keyOrder = Array<Key>()
//your custom implementation here
//including tracking for your dictionary order
}
您可以重载下标方法,以便它将键附加到 keyOrder
数组。然后提供一个迭代器,它将以正确的顺序 return (Key, Value)
元组。
您可能甚至不需要遵守 Collection
,但这是免费获得大量功能的好方法。
以下是一个符合 Collection 的结构,它委托给了一个字典。修改任何需要都相当容易。
public struct MyDictionary<Key: Hashable, Value: MyKindOfValue>: Collection {
public typealias DictionaryType = Dictionary<Key, Value>
private var dictionary: DictionaryType
//Collection: these are the access methods
public typealias IndexDistance = DictionaryType.IndexDistance
public typealias Indices = DictionaryType.Indices
public typealias Iterator = DictionaryType.Iterator
public typealias SubSequence = DictionaryType.SubSequence
public var startIndex: Index { return dictionary.startIndex }
public var endIndex: DictionaryType.Index { return dictionary.endIndex }
public subscript(position: Index) -> Iterator.Element { return dictionary[position] }
public subscript(bounds: Range<Index>) -> SubSequence { return dictionary[bounds] }
public var indices: Indices { return dictionary.indices }
public subscript(key: Key)->Value? {
get { return dictionary[key] }
set { dictionary[key] = newValue }
}
public func index(after i: Index) -> Index {
return dictionary.index(after: i)
}
//Sequence: iteration is implemented here
public func makeIterator() -> DictionaryIterator<Key, Value> {
return dictionary.makeIterator()
}
//IndexableBase
public typealias Index = DictionaryType.Index
}
我可以将 Swift
Dictionary
子类化,以便我可以将我的自定义 Dictionary
传递给需要普通 Dictionary
的方法吗?
编辑
不,swift中的字典和数组是结构体,不支持继承。 "personalize" 字典的唯一方法是使用扩展。
Swift 字典是结构,而不是 类,因此它们不能被子类化。理想情况下,您正在使用的方法将被声明为采用适当约束的通用 CollectionType(或 ExtensibleCollectionType 或 SequenceType,视情况而定),而不是具体的字典。
如果出于某种原因这对您不起作用,您可以改为子类化 NSDictionary。
(编辑)正如 Antonio 指出的那样,您可以执行扩展 Dictionary { … } 以向 Dictionary 结构添加内容,这在某些情况下可以取代子类化。
虽然我同意这里的大部分评论(你不能子class一个Struct
,设计它不是class),您可能会通过符合 CollectionType
的自定义 Struct
(现在在 Swift 3.0 中重命名为 Collection
)获得您想要的结果:
struct YourCustomDictionary<Key : Hashable, Value>: Collection {
private var elements = Dictionary<Key, Value>()
private var keyOrder = Array<Key>()
//your custom implementation here
//including tracking for your dictionary order
}
您可以重载下标方法,以便它将键附加到 keyOrder
数组。然后提供一个迭代器,它将以正确的顺序 return (Key, Value)
元组。
您可能甚至不需要遵守 Collection
,但这是免费获得大量功能的好方法。
以下是一个符合 Collection 的结构,它委托给了一个字典。修改任何需要都相当容易。
public struct MyDictionary<Key: Hashable, Value: MyKindOfValue>: Collection {
public typealias DictionaryType = Dictionary<Key, Value>
private var dictionary: DictionaryType
//Collection: these are the access methods
public typealias IndexDistance = DictionaryType.IndexDistance
public typealias Indices = DictionaryType.Indices
public typealias Iterator = DictionaryType.Iterator
public typealias SubSequence = DictionaryType.SubSequence
public var startIndex: Index { return dictionary.startIndex }
public var endIndex: DictionaryType.Index { return dictionary.endIndex }
public subscript(position: Index) -> Iterator.Element { return dictionary[position] }
public subscript(bounds: Range<Index>) -> SubSequence { return dictionary[bounds] }
public var indices: Indices { return dictionary.indices }
public subscript(key: Key)->Value? {
get { return dictionary[key] }
set { dictionary[key] = newValue }
}
public func index(after i: Index) -> Index {
return dictionary.index(after: i)
}
//Sequence: iteration is implemented here
public func makeIterator() -> DictionaryIterator<Key, Value> {
return dictionary.makeIterator()
}
//IndexableBase
public typealias Index = DictionaryType.Index
}