Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何为特定类型的阵列扩展阵列功能?_Arrays_Swift_Class_Swift2 - Fatal编程技术网

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]()

}