0

我想将对象的方法存储在可变集合中。我可以毫无问题地添加该方法,但无法删除它:

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

我想做的事可能吗?

4

1 回答 1

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

可能吗?哎呀!尽可能!

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 反射。

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
于 2013-06-29T22:44:06.500 回答