12

いくつかのメソッドを持つクラス C があるとしましょう

def class C {
  def f1():Int = ...
  def f2():Int = ...
}

ここで、C の 2 つのインスタンスと C のメソッドを受け取るメソッドが必要ですが、f1 と f2 の型が何であるかも、それらを呼び出す方法もわかりません。私はそれが次のようになると思います

def cmp(first:C, second:C, t:() => Int): Boolean = {
  first.t < second.t
}

これは、t が C のメソッドではないことを訴えています。確かに、これを表現する方法があるに違いありません。

4

3 に答える 3

14
def cmp(first:C, second:C, t: C => Int): Boolean = {
  t(first) < t(second)
}

それで...

val c1 = new C
val c2 = new C
cmp(c1, c2, _.f1())
cmp(c1, c2, _.f2())

これは無名関数を使用しています。最後の 2 行は次と同等です。

cmp(c1, c2, {c: C => c.f1()})
cmp(c1, c2, {c: C => c.f2()})

何らかのリフレクションを使用しない限り、メソッド自体への参照を渡すことはできません。

于 2013-07-01T23:13:08.420 に答える
9

代わりにメソッド参照を渡すことができます:

object DoOperation extends App {

  class C(val x: Int) {
      def f1():Int = x-1
      def f2():Int = x+1
   }


  def cmp(first: () => Int, second: () => Int): Boolean = {
    first() < second()
  }

  override def main(args: Array[String]) {
      println(cmp(new C(1).f1,new C(0).f2)) //prints "true"
      println(cmp(new C(1).f2,new C(1).f1)) //prints "false"
  }

}

メソッドは、対応するオブジェクト インスタンスに対して閉じられるため、最終的な効果は、達成したいと思われるものと同じになります。

于 2013-07-01T23:19:59.497 に答える
0

このアプローチも機能する場合があります。

@ class myClass {
    def double(x: Int): Int = x * 2
    def triple(x: Int): Int = x * 3
  }
defined class myClass

@ val instance = new myClass
instance: myClass = ammonite.$sess.cmd0$myClass@4195105b

@ def callArbitraryMethod(instance: myClass, f: (myClass, Int) => Int, x: Int): Int = f(instance, x)
defined function callArbitraryMethod

@ val f = (instance: myClass, x: Int) => instance.double(x)
f: (myClass, Int) => Int = ammonite.$sess.cmd3$$$Lambda$1965/11731022@3b8b4846

@ callArbitraryMethod(instance, f, 10)
res4: Int = 20
于 2018-03-22T18:16:47.603 に答える