7

オプションとしてクロージャーをメソッドに渡したいのですが、以下に示すことを行っています。以下に示すように、コンパイルエラーが発生します。オプションのクロージャーパラメーターを関数に渡すことは可能ですか?

def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) {
    // do some processing with a and b
    optionalMethod match {
      case Some(optionalMethod) => {
        optionalMethod("a",3)
      }
      case _
      log("no optional method passed")
    }
}

// definition of optMethod in some other place
val optMethod = (c: String, d: Int) => {
  // some processing with c, d and external values 
}

// invoke
sampleMethod("hi", "bye", optMethod) => FAILS TO COMPILE

ERROR = type mismatch. expecting Option[(String, Int) => Unit] found (String, Int) => Unit
4

4 に答える 4

8

エラーメッセージは非常に明白です:sampleMethod期待してOptionいますが、ストレートな関数値を渡しています (でラップされていませんSome)。

これを修正する最も簡単な方法は、次のようにラップoptMethodすることSomeです。

sampleMethod("hi", "bye", Some(optMethod))

しかし、単純に を実行できるようにしたい場合sampleMethod("hi", "bye", optMethod)は、オーバーロードされた の定義を追加できますsampleMethod

object Test {
  def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) {
    // do some processing with a and b
    optionalMethod match {
      case Some(optionalMethod) => {
        optionalMethod("a",3)
      }
      case _ => log("no optional method passed")
    }
  }
  def sampleMethod(a: String, b: String) { sampleMethod(a, b, None) }
  def sampleMethod(a: String, b: String, optionalMethod: (String, Int) => Unit) {
    sampleMethod(a, b, Some(optionalMethod)) 
  }
}

val optMethod = (c: String, d: Int) => {
  // some processing with c, d and external values 
}

// invoke
Test.sampleMethod("hi", "bye", optMethod) // Now Compiles fine
Test.sampleMethod("hi", "bye") // This too
于 2013-02-08T15:16:50.837 に答える
6

前に指摘したように、メソッドは。Optionを含む値を期待しますoptionalMethodOptionしたがって、値を渡す必要があります。

// invoke with method
sampleMethod("hi", "bye", Some(optMethod))
// invoke without method
sampleMethod("hi", "bye", None)

値を避けたい場合Option(特に、を避けたい場合None)、次のことを試すことができます。

def sampleMethod(a: String, b: String, optionalMethod: (String, Int) => Unit = (_, _) => log("no optional method passed")) {
  optionalMethod("a", 3)
}

// invoke with method
sampleMethod("hi", "bye", optMethod)
// invoke without method
sampleMethod("hi", "bye")
于 2013-02-08T15:01:54.697 に答える
0

より明確:

scala> def sampleMethod(a: String, b: String, optionalMethod: Option[(String, Int) => Unit]) {
     | optionalMethod.map(f => f("a", 3))
     | }
sampleMethod: (a: String, b: String, optionalMethod: Option[(String, Int) => Unit])Unit


scala> sampleMethod("A", "A", Some((c:String, d:Int) => println(s"Hello wolrd $c...$d")))
Hello wolrd a...3

オプション関数の周りに「Some()」を追加するだけです

于 2013-02-08T15:07:44.283 に答える