문제

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.

다른 팁

You can define foo and bar as function literals:

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>)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top