从可变集中删除函数

时间:2013-06-29 22:34:27

标签: scala

我想将对象的方法存储在一个可变的Set中。我可以毫无问题地添加方法,但无法将其删除:

scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

scala> class c {
     | def f(value: Double) {
     | println(value)
     | }
     | }
defined class c

scala> val o = new c
o: c = c@4b08e64d

scala> val s = Set.empty[Function1[Double, Unit]]
s: scala.collection.mutable.Set[Double => Unit] = Set()

scala> s add o.f
res0: Boolean = true

scala> s.size
res1: Int = 1

scala> s remove o.f
res2: Boolean = false

scala> s.size
res3: Int = 1

如果我创建一个用于保存c类型对象的集合,则一切都按预期工作。

scala> val s2 = Set.empty[c]
s2: scala.collection.mutable.Set[c] = Set()

scala> s2 add o
res4: Boolean = true

scala> s2.size
res5: Int = 1

scala> s2 remove o
res6: Boolean = true

scala> s2.size
res7: Int = 0

我想做的是什么?

1 个答案:

答案 0 :(得分:1)

o.f类似于函数指针,但实际上并非如此。

scala> o.f _
res6: Double => Unit = <function1>

scala> res6.##
res7: Int = 1849765122

scala> o.f _
res8: Double => Unit = <function1>

scala> res8.##
res9: Int = 509798553

有可能吗? Mais oui! C'est可能!

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> import reflect.runtime.currentMirror
import reflect.runtime.currentMirror

scala> currentMirror reflect o
res12: reflect.runtime.universe.InstanceMirror = instance mirror for c@5a8c6475

scala> typeOf[c]
res13: reflect.runtime.universe.Type = c

scala> .declaration(TermName("f"))
res14: reflect.runtime.universe.Symbol = method f

scala> res12 reflectMethod res14.asMethod
res15: reflect.runtime.universe.MethodMirror = method mirror for c.f(value: scala.Double): scala.Unit (bound to c@5a8c6475)

scala> val ms = Set.empty[MethodMirror]
ms: scala.collection.mutable.Set[reflect.runtime.universe.MethodMirror] = Set()

scala> .add(res15)
res16: Boolean = true

scala> ms.remove(res15)
res17: Boolean = true

编辑:

忽略我的法语,无论如何都是镜像特定的,所以这不是一种改进。

换句话说,使用java reflection。

scala> classOf[c].getMethod("f", classOf[Double])
res23: java.lang.reflect.Method = public void c.f(double)

scala> res23.##
res24: Int = 521628901

scala> classOf[c].getMethod("f", classOf[Double])
res25: java.lang.reflect.Method = public void c.f(double)

scala> res25.##
res26: Int = 521628901