背景
为方便起见,我使用了这个别名:
typealias Deck = [Int]
我的需求正在扩大,所以我现在将代码转换为:
class Deck
{
var deck : [Int]
// ... other members
}
我能够将我的大部分电话委托给self.deck
,但在谷歌搜索之后,我仍然无法确定如何委派此电话:
let deck = Deck()
for i in deck[0..<5] { } // <--- PROBLEMS HERE
问题
如何实施此次通话的委派?
我认为它与subscript
和range
(或者sequence
?)有关,但我没有运气搜索这两个主题的交集。
答案 0 :(得分:7)
对于deck[0..<5]
,您需要实施Sliceable
协议
需要CollectionType
和SequenceType
。
以下示例实现MutableCollectionType
,以便设置
元素也被转发到数组:
class Deck
{
typealias DeckValueType = Int
typealias DeckIndexType = Array<DeckValueType>.Index
var deck : [DeckValueType] = [0, 1, 2, 3, 4, 5, 6] // just for demonstration ...
}
extension Deck : SequenceType {
func generate() -> IndexingGenerator<[DeckValueType]> {
return deck.generate()
}
}
extension Deck: MutableCollectionType {
var startIndex : DeckIndexType { return deck.startIndex }
var endIndex : DeckIndexType { return deck.endIndex }
subscript(index: DeckIndexType) -> DeckValueType {
get {
return deck[index]
}
set(newValue) {
deck[index] = newValue
}
}
}
extension Deck : Sliceable {
subscript (bounds: Range<DeckIndexType>) -> ArraySlice<DeckValueType> {
get {
return deck[bounds]
}
}
}
然后它起作用:
let deck = Deck()
for i in deck[0..<5] {
println(i)
}
类型别名不是绝对必要的,但它们使它更容易
区分Int
是用作数组元素的类型还是用作
输入数组索引。
此外,您可以将所有代码放入类定义中。我选择了单独的 扩展,以明确哪种方法需要哪种方法。