Arrays 如何为特定类型的阵列扩展阵列功能?
(使用我常用的扑克牌示例)Arrays 如何为特定类型的阵列扩展阵列功能?,arrays,swift,class,swift2,Arrays,Swift,Class,Swift2,(使用我常用的扑克牌示例) 我正在尝试创建一个通用的卡片集合,一个卡片组和一个手都将从中继承。牌组和手牌都需要排序或洗牌,但会有一些区别,例如初始化和移除其他地方使用的牌的方法是否为交易(对于牌组)、播放、或放弃(对于手牌) class-CardCollection:{ var集合=[卡]() //CardCollection特定功能 //传递函数 func追加(新卡:卡){ 集合。附加(新卡) } } 课程组:CardCollection{ //甲板特定功能 } 班手:卡片收集{ //手特定功
我正在尝试创建一个通用的
卡片集合
,一个卡片组
和一个手
都将从中继承。牌组和手牌都需要排序或洗牌,但会有一些区别,例如初始化和移除其他地方使用的牌的方法是否为交易
(对于牌组
)、播放
、或放弃
(对于手牌
)
class-CardCollection:{
var集合=[卡]()
//CardCollection特定功能
//传递函数
func追加(新卡:卡){
集合。附加(新卡)
}
}
课程组:CardCollection{
//甲板特定功能
}
班手:卡片收集{
//手特定功能
}
我目前实现它的方式(见上文)是使用一个包含一个卡数组的类,但是如果不编写大量的传递函数,使我的类作为一个数组符合所有协议,我就不能像使用数组一样使用我的类
我需要的是一种方法,让我可以为卡片组中的卡片做(好像deck
只是一个Array
)之类的事情,而无需编写大量的包装函数,只需让CardCollection
符合所有必要的协议
如何使CardCollection的功能像一个数组
,而不对数组
使用的协议所使用的每个函数都使用传递函数?您可以定义一个继承自的CardCollection
协议
RangeReplacableCollectionType
,
以及一个协议扩展,带有转发所有数据的默认实现
对基础集合数组的访问方法:
struct Card {
// Simplified for demonstration purposes:
let rank : Int
let suit : Int
}
protocol CardCollection : RangeReplaceableCollectionType {
var collective : [Card] { get set }
}
extension CardCollection {
var startIndex : Int { return collective.startIndex }
var endIndex : Int { return collective.endIndex }
subscript(position : Int) -> Card {
get {
return collective[position]
}
set(newElement) {
collective[position] = newElement
}
}
mutating func replaceRange<C : CollectionType where C.Generator.Element == Card>(subRange: Range<Int>, with newElements: C) {
collective.replaceRange(subRange, with: newElements)
}
}
protocol ElementCollection : RangeReplaceableCollectionType {
typealias Element
var elements : [Element] { get set }
}
extension ElementCollection {
var startIndex : Int { return elements.startIndex }
var endIndex : Int { return elements.endIndex }
subscript(position : Int) -> Element {
get {
return elements[position]
}
set(newElement) {
elements[position] = newElement
}
}
mutating func replaceRange<C : CollectionType where C.Generator.Element == Element>(subRange: Range<Int>, with newElements: C) {
elements.replaceRange(subRange, with: newElements)
}
}
两者都符合RangeReplacableCollectionType
,可以进行处理
像一个数组:
var deck = Deck()
deck.append(Card(rank: 1, suit: 1))
deck[0] = Card(rank: 2, suit: 3)
for card in deck {
print(card)
}
var hand = Hand()
hand.append(deck.first!)
如果Deck
/Hand
是类而不是结构,那么它们
需要是final
或具有required init()
方法,
比较
更一般地说,您可以定义ElementCollection
协议(独立于卡
类型)
其行为类似于数组(通过符合
RangeReplacableCollectionType
),并将访问转发到
底层元素
数组:
struct Card {
// Simplified for demonstration purposes:
let rank : Int
let suit : Int
}
protocol CardCollection : RangeReplaceableCollectionType {
var collective : [Card] { get set }
}
extension CardCollection {
var startIndex : Int { return collective.startIndex }
var endIndex : Int { return collective.endIndex }
subscript(position : Int) -> Card {
get {
return collective[position]
}
set(newElement) {
collective[position] = newElement
}
}
mutating func replaceRange<C : CollectionType where C.Generator.Element == Card>(subRange: Range<Int>, with newElements: C) {
collective.replaceRange(subRange, with: newElements)
}
}
protocol ElementCollection : RangeReplaceableCollectionType {
typealias Element
var elements : [Element] { get set }
}
extension ElementCollection {
var startIndex : Int { return elements.startIndex }
var endIndex : Int { return elements.endIndex }
subscript(position : Int) -> Element {
get {
return elements[position]
}
set(newElement) {
elements[position] = newElement
}
}
mutating func replaceRange<C : CollectionType where C.Generator.Element == Element>(subRange: Range<Int>, with newElements: C) {
elements.replaceRange(subRange, with: newElements)
}
}
只是想澄清一下:我仍然需要为协议扩展中列出的所有方法提供转发,对吗?@cjm:不,只有那些没有默认实现的方法。上面的示例只实现了startIndex、endIndex、subscript(来自可索引协议)和replaceRange的转发。其他方法的默认实现,如first、append或generate(用于for..in),然后使用这些方法。那么我肯定错过了一些没有默认实现的方法(很可能是协议扩展),因为它抱怨类型“Deck”不符合协议“RangeReplacableCollectionType”
。NEVERMIND(如上所述):我太傻了,忘了在问题导航器中展开问题以获取详细信息
struct Card {
// Simplified for demonstration purposes:
let rank : Int
let suit : Int
}
struct Deck: ElementCollection {
var elements = [Card]()
}
struct Hand: ElementCollection {
var elements = [Card]()
}