我在函数中使用val时出错,但在REPL中自己访问val时则出错。

时间:2017-06-07 20:48:20

标签: scala

我正在编写Scala代码来搜索QuadTree。我对Scala很新,所以这可能是一个简单的问题:当我尝试在函数中使用error: value rec not a member of QuadTree时,为什么会得到tree.rec,但如果我要求REPL评估{{} 1}},它成功返回数据?

无论如何,我已经开始使用这些课程了:

tree.rec

所以我定义了一个Rectangle,然后是一个QuadTree,它可以有一个值,并且包含一个Node,一个Leaf或Empty。

接下来我有一个函数检查两个矩形是否重叠称为case class Rectangle (minx: Int, maxx: Int, miny: Int, maxy: Int) abstract class QuadTree case class Node (value : Int, nw : QuadTree, ne: QuadTree, sw: QuadTree, se: QuadTree, rec: Rectangle) extends QuadTree case class Leaf (value : Int, rec: Rectangle) extends QuadTree case class Empty (value: Int, rec: Rectangle) extends QuadTree ,如果两个输入矩形重叠则返回rectangles_Overlap,如果没有重叠则返回True

如果我定义

False

如果我想获得树的大小,我可以输入REPL

val query = Rectangle(1, 8, 8, 16)
val tree1 = Node(13,Node(12,Leaf(7,Rectangle(1,4,12,16)),Leaf(3,Rectangle(4,8,12,16)),Leaf(2,Rectangle(1,4,8,12)),Empty(0,Rectangle(4,8,8,12)),Rectangle(1,8,8,16)),Empty(0,Rectangle(8,16,8,16)),Empty(0,Rectangle(1,8,1,8)),Leaf(1,Rectangle(8,16,1,8)),Rectangle(1,16,1,16))

我也可以使用我的scala> tree1.rec res0: Rectangle = Rectangle(1,16,1,16) 方法查看查询Rectangle是否与树Rectangle重叠。

rectangles_Overlap

但如果我尝试在另一个函数中使用scala> rectangles_Overlap(query, tree1.rec) res1: Boolean = true ,那就不开心了!

rectangles_Overlap(query, tree1.rec)

然后使用def queryBoolean(query: Rectangle, tree: QuadTree): Boolean = { if(rectangles_Overlap(query, tree.rec)) { println("Yay they overlap so I can do other stuff...") // I want to add other code here after I get this working true } else { println("Nah, they don't overlap, don't need to do anything") false } } 调用该函数,我收到此错误:

queryBoolean(query, tree1)

所以我的问题是:为什么我可以在REPL中评估<console>:17: error: value rec is not a member of QuadTree if (rectangles_Overlap(query, tree.rec)) { ,但在没有错误的情况下不能在函数中使用tree1.rec

我最初的想法是,我可能正在超载......但tree.rec在所有rec中总是Rectangle。所以我不相信我超载了什么?

2 个答案:

答案 0 :(得分:2)

这是事实。 rec,即Rectangle的类型,是不是 QuadTree的成员。如果您从QuadTree更改为Node,它将起作用。否则它也必须在QuadTree中存在。

def queryBoolean(query: Rectangle, tree: Node): Boolean 

添加到QuadTree作为val(访问它需要val),然后你需要覆盖并调用超级构造函数,如下所示:

  abstract class QuadTree(val rec: Rectangle)
  case class Node (value : Int, nw : QuadTree, ne: QuadTree, sw: QuadTree, se: QuadTree, override val rec: Rectangle) extends QuadTree(rec)
  case class Leaf (value : Int, override val rec: Rectangle) extends QuadTree(rec)
  case class Empty (value: Int, override val rec: Rectangle) extends QuadTree(rec)

答案 1 :(得分:1)

这是因为rec没有为类QuadTree定义,而是仅为其子类定义,因此没有值可以调用。这在REPL上正常工作的原因是因为它的定义方式。您将其定义为

val tree1 = Node(/*some params*/)

这表示它的类型为Node,而不是QuadTree。由于Node有一个已定义的rec参数,所以一切正常。但是在该方法中,您传入原始QuadTree,因此不定义rec。

要使其正常工作,请将rec添加到QuadTree类,或者传入特定的子类型,该子类型已定义了正确的参数。