我已经在Scala列表中添加了一个函数,现在我该如何删除它?

时间:2013-09-28 02:48:51

标签: scala first-class-functions

给出以下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被计算为布尔值。

2 个答案:

答案 0 :(得分:7)

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

换句话说,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现在将按预期工作。

答案 1 :(得分:1)

您可以将foobar定义为函数文字:

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