Swift:Can';t使用嵌套/链接的泛型类型约束(策略模式)
我正在Swift中实现一个随机树数据结构。为了限制树的宽度和深度,我决定使用策略模式 我的政策是这样的: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> { /* ... */ } 我有一个基类,看起来
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())