Swift泛型树转换为int
我试图创建一个与树一起使用的节点,这是我使用泛型创建的节点类Swift泛型树转换为int,swift,generics,tree,Swift,Generics,Tree,我试图创建一个与树一起使用的节点,这是我使用泛型创建的节点类 class TreeNode<T: Comparable, Randomizable> { var object: T var left: TreeNode? var right: TreeNode? init(object: T, left: TreeNode?, right: TreeNode?) { self.object = object self.left = left self.rig
class TreeNode<T: Comparable, Randomizable> {
var object: T
var left: TreeNode?
var right: TreeNode?
init(object: T, left: TreeNode?, right: TreeNode?) {
self.object = object
self.left = left
self.right = right
}
}
现在,我有另一个函数,它将用随机整数填充树
class Tree<T: Comparable, Randomizable> {
var root: TreeNode<T, Randomizable>? = nil
func generateIntTree(depth: Int = 5, maxNumNodesPerLevel: Int = 2, minValue: Int = 0, maxValue: Int = 20) {
root = TreeNode<Int, Int>.init(object: Int.random(in: minValue...maxValue), left: nil, right: nil)
}
我收到的错误消息是无法将“TreeNode”类型的值分配给“TreeNode”类型
我应该用什么来代替吗?但是我仍然想保留我的扩展。除了T:Comparable,Randomizable和T:Comparable&Randomizable的错误之外,您还存在硬编码Int.random的问题。。。在对TreeNode?类型的根的赋值中?。这样的赋值只有在Int和T是同一类型时才有效,这在无界泛型上下文(例如树的声明)中是不正确的。这只在条件扩展中是正确的,扩展树中的T==Int
当前在类中有两个通用参数:一个称为T,需要可比较,另一个称为Randomizable,没有任何约束。我假设您想要TreeNode即使如此,generateIntTree也不能像现在这样存在于TreeNode声明下,因为它不是泛型的。它将T硬编码为Int,这只有在这是TreeNode上的条件扩展时才可能:扩展TreeNode,其中T==Int,这违背了它是泛型的目的。您如何解决这个问题?我想创建一棵树,以便能够容纳任何符合可比较性和随机性的内容。但我也希望有一个函数来创建一个以int为元素的树的实例。随机化它与R相同。它只是一个泛型类型,可以是任何类型。显示根对象声明和generateIntTree声明的位置是毫无意义的,谢谢。我认为这一点很重要。@Latcie我还建议您考虑使用随机化协议,不管它是什么。将generateIntTree更改为GeneratorDomainTree,将扩展更改为extension Tree,其中T:Randomizable{…},并调用Randomizable的协议方法生成有效负载,而不是硬编码随机值的类型。就目前而言,它只是对树类型的任意多余约束。没有理由不能有一个非随机化元素树。
// Stubs to make it compile
public protocol Randomizable {}
extension Int: Randomizable {}
private class TreeNode<T: Comparable & Randomizable> {
var object: T
var left: TreeNode?
var right: TreeNode?
init(object: T, left: TreeNode?, right: TreeNode?) {
self.object = object
self.left = left
self.right = right
}
}
public class Tree<T: Comparable & Randomizable> {
fileprivate var root: TreeNode<T>?
fileprivate init(root: TreeNode<T>? = nil) { self.root = root }
}
extension Tree where T == Int {
public func generateIntTree(
depth: Int = 5,
maxNumNodesPerLevel: Int = 2,
minValue: Int = 0,
maxValue: Int = 20
) -> Tree<Int> {
return Tree(root:
generateIntTree(
depth: depth,
maxNumNodesPerLevel: maxNumNodesPerLevel,
minValue: minValue,
maxValue: maxValue
)
)
}
private func generateIntTree(
depth: Int = 5,
maxNumNodesPerLevel: Int = 2,
minValue: Int = 0,
maxValue: Int = 20
) -> TreeNode<Int>? {
if depth == 0 { return nil }
let payload = Int.random(in: minValue...maxValue)
return TreeNode(
object: payload,
left: generateIntTree(
depth: depth - 1,
minValue: minValue,
maxValue: maxValue
),
right: generateIntTree(
depth: depth - 1,
minValue: minValue,
maxValue: maxValue
)
)
}
}
extension Tree where T == Int {
public func generateIntTree(
depth: Int = 5,
maxNumNodesPerLevel: Int = 2,
valueRange: ClosedRange<Int> = 0...20
) -> Tree<Int> {
return Tree(root:
generateIntTree(
depth: depth,
maxNumNodesPerLevel: maxNumNodesPerLevel,
valueRange: valueRange
)
)
}
private func generateIntTree(
depth: Int = 5,
maxNumNodesPerLevel: Int = 2,
valueRange: ClosedRange<Int> = 0...20
) -> TreeNode<Int>? {
if depth == 0 { return nil }
let payload = Int.random(in: valueRange)
return TreeNode(
object: payload,
left: generateIntTree(depth: depth - 1, valueRange: valueRange),
right: generateIntTree(depth: depth - 1, valueRange: valueRange)
)
}
}