Given the following Scala code:
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
I've added two functions to my buffer. Now, how do I remove one?
buffer -= foo
doesn't work because foo is evaluated to a boolean before any comparisons.
You misunderstand the reason why your current code is not working. Removing objects in this way relies on the ==
operator, which for functions is defined using the object identity only. This means that you must ensure that you have a stable value for the function that you are adding if you want to remove it again. You are currently using anonymous function literals ('boxed' from the method references), which cannot be recreated.
In other words, buffer += foo
is equivalent to buffer += (foo _)
, and foo _
will give you a different function object each time. Try this:
buffer += foo
buffer += foo
buffer.map(System.identityHashCode(_))
res4: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(944601779, 1722981029)
Oops, two different objects, we were expecting to have two references to the same one.
Now try
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)
Ah, that's better! buffer -= fooRef
will now work as expected.