给出以下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被计算为布尔值。
答案 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)
您可以将foo
和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>)