В дополнение к ошибкам T: Comparable, Randomizable
и T: Comparable & Randomizable
у вас также есть проблема с жестким кодированием Int.random(...)
в присвоении root
типа TreeNode<T>?
. Такое присваивание допустимо только в том случае, если Int
и T
относятся к одному и тому же типу, что неверно в неограниченном обобщенном контексте c (например, объявление Tree<T>
). Это верно только для условного расширения: extension Tree where T == Int
// 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
)
)
}
}
Кроме того, не передавайте min
/ max
Int
значения, подобные этому. Как вы видите, это действительно неуклюже (всегда нужно обойти две разные вещи), и это подвержено ошибкам (вы не можете легко случайно назначить min
, где max
принадлежит, или наоборот). Range<T>
существует. Используй это. Посмотрите, насколько приятнее становится:
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)
)
}
}