3

给定以下 Scala 代码:

val buffer = new scala.collection.mutable.ArrayBuffer[Function0[Boolean]]
def foo(): Boolean = { println("foo"); false }
def bar(): Boolean = { println("bar"); true }

buffer += foo
buffer += bar

我在缓冲区中添加了两个函数。现在,我如何删除一个?

buffer -= foo不起作用,因为 foo 在任何比较之前被评估为布尔值。

4

2 回答 2

7

您误解了当前代码不起作用的原因。以这种方式移除对象依赖于==操作符,对于函数,它仅使用对象标识来定义。这意味着如果要再次删除它,您必须确保要添加的函数具有稳定的值。您当前正在使用无法重新创建的匿名函数文字(来自方法引用的“装箱”)。

换句话说,buffer += foo等价于buffer += (foo _),并且foo _每次都会给你一个不同的函数对象。试试这个:

buffer += foo
buffer += foo
buffer.map(System.identityHashCode(_))
res4: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(944601779, 1722981029)

糟糕,两个不同的对象,我们期望有两个对同一个对象的引用。

现在试试

val fooRef:Function0[Boolean] = foo // or val fooRef = foo _
buffer += fooRef
buffer += fooRef
buffer.map(System.identityHashCode(_))
res8: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1732011089, 1732011089)

啊,这样更好!buffer -= fooRef现在将按预期工作。

于 2013-09-28T06:19:37.600 回答
1

您可以将fooand定义bar为函数字面量:

scala>  val buffer = collection.mutable.ArrayBuffer.empty[Function0[Boolean]]
buffer: scala.collection.mutable.ArrayBuffer[() => Boolean] = ArrayBuffer()

scala>  val foo = () => { println("foo"); false }
foo: () => Boolean = <function0>

scala>  val bar = () => { println("bar"); true }
bar: () => Boolean = <function0>

scala>  buffer += foo
res0: buffer.type = ArrayBuffer(<function0>)

scala>  buffer += bar
res1: buffer.type = ArrayBuffer(<function0>, <function0>)

scala>  buffer -= foo
res2: buffer.type = ArrayBuffer(<function0>)
于 2013-09-28T03:49:40.567 回答