Swift:Can';t使用嵌套/链接的泛型类型约束(策略模式)

Swift:Can';t使用嵌套/链接的泛型类型约束(策略模式),swift,generics,swift2,swift2.2,Swift,Generics,Swift2,Swift2.2,我正在Swift中实现一个随机树数据结构。为了限制树的宽度和深度,我决定使用策略模式 我的政策是这样的: protocol BaseTreeNodePolicy { static var maximumDepth: Int { get } static var maximumWidth: Int { get } } class BaseTreeNode<PolicyType: BaseTreeNodePolicy> { /* ... */ } 我有一个基类,看起来

我正在Swift中实现一个随机树数据结构。为了限制树的宽度和深度,我决定使用策略模式

我的政策是这样的:

protocol BaseTreeNodePolicy {
    static var maximumDepth: Int { get }
    static var maximumWidth: Int { get }
}
class BaseTreeNode<PolicyType: BaseTreeNodePolicy> { /* ... */ }
我有一个基类,看起来像这样:

protocol BaseTreeNodePolicy {
    static var maximumDepth: Int { get }
    static var maximumWidth: Int { get }
}
class BaseTreeNode<PolicyType: BaseTreeNodePolicy> { /* ... */ }
这一行:

// 'ChildType' is not a subtype of 'ActionNode<PolicyType>'
sequence.reserveCapacity(42)
// Type 'PolicyType' does not conform to protocol 'BaseTreeNodePolicy'
let descendant = ChildType(generator: generator, maxDepth: maxDepth - 1)
我不知道怎么回事,因为我清楚地说明了类型要求,即
ChildType:ActionNode
PolicyType:BaseTreeNodePolicy
位于声明的标题部分

有什么不对劲吗

提前谢谢!
Petr.

编辑:重新做以达到您的目的:

ActionNode
不属于参数列表。您仅在
PolicyType
上进行参数化:

final class SequenceNode<PolicyType: BaseTreeNodePolicy> {
    typealias ChildType = ActionNode<PolicyType>
    var sequence = [ChildType]()
    func addRandomDescendants(generator: EntropyGenerator, maxDepth: Int) {
        sequence.reserveCapacity(42)
    }
}

这比我想象的要简单,试试这个。很好的解决方案,但是如果我想
ChildType
成为
ActionNode
的任何子类,我该怎么办?谢谢你提供了非常详细和全面的答案。这正是我想要的。我只是没有意识到一个策略可以被实例化(我有C++背景,你可以在这些方面有更多的乐趣)。我希望它也能帮助其他开发人员。:-)
class _ERROR_SequenceNode<PolicyType, ChildType where PolicyType: BaseTreeNodePolicy, ChildType: ActionNode<PolicyType>> { }
protocol BaseTreeNodePolicy {
    var maximumDepth: Int { get }
    var maximumWidth: Int { get }
}

class BaseTreeNode {
    var policy: BaseTreeNodePolicy

    required init(policy: BaseTreeNodePolicy) {
        self.policy = policy
    }

    // Use 'policy' anywhere now. You've defined a protocol, don't generically parameterize
}

class ValueNode: BaseTreeNode {
    required init(policy: BaseTreeNodePolicy) {
        super.init(policy: policy)
    }
}

class ActionNode: BaseTreeNode {
    required init(policy: BaseTreeNodePolicy) {
        super.init(policy: policy)
    }
}

class SequenceNode<ChildType: ActionNode>: BaseTreeNode {
    var sequence: [ChildType] = []

    required init(policy: BaseTreeNodePolicy) {
        super.init(policy: policy)
    }

    func addRandomDescendants() {
        let c = ChildType(policy: policy)
        sequence.reserveCapacity(42)
    }
}

class FooNode: ActionNode {}

class MyPolicy: BaseTreeNodePolicy {
    var maximumDepth = 3
    var maximumWidth = 5
}

let s = SequenceNode<FooNode>(policy: MyPolicy())