此Functor表示使用相关(可变)x位置和y位置移动的行为:
final class Moving(var xPos: Int, var yPos: Int) extends Function2[Int, Int, Unit] {
override def apply(dX: Int, dY: Int): Unit = {
xPos += dX
yPos += dY
println("xPos: " + xPos + " yPos: " + yPos)
}
}
问题是它没有按预期运行。当我运行此代码时:
def move = new Moving(0, 0)
def main(args: Array[String]) {
move.apply(1,1)
move.apply(2,2)
move.apply(3,3)
}
我得到了这个输出:
xPos: 1 yPos: 1
xPos: 2 yPos: 2
xPos: 3 yPos: 3
x位置和y位置在修改之前似乎回到了它们的初始值。我希望输出像这样:
xPos: 1 yPos: 1
xPos: 3 yPos: 3
xPos: 6 yPos: 6
为什么此功能不能按预期运行?
*解决方案*
val motion = new Moving(0, 0)
def move = motion // this just returns the function object
def main(args: Array[String]) {
move.apply(1,1)
move.apply(2,2)
move.apply(3,3)
}
答案 0 :(得分:3)
这是因为您将move
声明为方法,而不是字段。这意味着每次引用move
时,它都会创建一个Moving
类的新实例供您使用。
将您的代码更改为:
val move = new Moving(0, 0)
使用val
代替def
,您每次都会获得相同的实例。
混乱来自Scala中函数和对象之间模糊的界限。您的Moving
类是一个函数,但由于它还保留了状态,因此您需要确保每次都对它执行相同的操作。在这种情况下使用def
声明了一个返回函数的方法,而不是每次只给你相同的函数。