Scala中奇怪的函数对象行为 - 可变函数变量正在重置

时间:2015-10-27 14:53:45

标签: scala

此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)
}

1 个答案:

答案 0 :(得分:3)

这是因为您将move声明为方法,而不是字段。这意味着每次引用move时,它都会创建一个Moving类的新实例供您使用。

将您的代码更改为:

val move = new Moving(0, 0)

使用val代替def,您每次都会获得相同的实例。

混乱来自Scala中函数和对象之间模糊的界限。您的Moving类是一个函数,但由于它还保留了状态,因此您需要确保每次都对它执行相同的操作。在这种情况下使用def声明了一个返回函数的方法,而不是每次只给你相同的函数。