我是Scala的新手。我正在尝试开发自己的不可变二叉搜索树。
首先,我开发了一个在其节点上使用Int
的二叉搜索树。之后,我决定开发通用的二叉搜索树。
当我编译这些代码时,我从终端获取了这些错误消息。
trait GenericBST[+T] {
def add[TT >: T](x: T): GenericBST[TT] = this match {
case Empty => Branch(x, Empty, Empty)
case Branch(d, l, r) =>
if(d > x) Branch(d, l.add(x), r)
else if(d < x) Branch(d, l, r.add(x))
else this
}
}
case class Branch[+T](x: T, left: GenericBST[T], right: GenericBST[T]) extends GenericBST[T]
case object Empty extends GenericBST[Nothing]
错误:值&lt;不是类型参数T的成员。
错误是明智的,我该如何解决?
别忘了我是Scala的新手,所以请详细解释一下。
答案 0 :(得分:4)
T
代表任何类型,但为了使用>
和<
,您需要一种有序排序的类型。
在scala中,它意味着您必须设置T
类型的边界,将其限制为T
存在的所有Ordering[T]
。您可以使用上下文绑定,或者等效地要求ord
类型的隐式Ordering[TT]
。
trait GenericBST[+A] {
def add[B >: A](x: B)(implicit ord: Ordering[B]): GenericBST[B] = {
import ord.mkOrderingOps
this match {
case Empty => Branch(x, Empty, Empty)
case Branch(e, l, r) =>
if (e > x) Branch(e, l.add(x), r)
else if (e < x) Branch(e, l, r.add(x))
else this
}
}
}
case class Branch[+A](x: A, left: GenericBST[A], right: GenericBST[A]) extends GenericBST[A]
case object Empty extends GenericBST[Nothing]
导入ord.mkOrderingOps
允许使用语法
e > x
而不是
ord.gt(e, x)
您也可以直接使用上下文绑定,但是需要一些额外的工作来获取范围内的隐式ord
(并且它可以说是不太可读):
def add[B >: A : Ordering](x: B): GenericBST[B] = {
val ord = implicitly[Ordering[B]]
import ord.mkOrderingOps
...
}
绝对不相关,但您可能想知道为什么我在我的示例中使用了A
和B
,而不是T
和TT
。根据{{3}}:
对于简单类型参数,应使用单个大写字母(来自英文字母),从
A
开始(这与以T
开头的Java约定不同)