2013-02-08 63 views
6

我想將一個閉包傳遞給一個方法作爲一個選項,我正在做如下所示。我得到一個編譯錯誤,如下所示。是否可以將一個可選的閉包參數傳​​遞給一個函數?如何將可選的閉包參數傳​​遞給函數?

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 
+0

sampleMethod(「hi」,「bye」,Some(optMethod)) – twillouer 2013-02-08 15:03:49

+0

optionalMethod.map(f => f(「a」,3))更清晰 – twillouer 2013-02-08 15:04:36

+1

只是因爲其他語言及其用戶羣體sl with不樂termino邏輯,我們不要在這裏做同樣的事情。 「關閉」是指在函數文字中使用自由變量(在該函數的主體中沒有綁定的名稱),並將這些引用「關閉」到詞法環境中。並非所有功能都涉及到關閉詞彙環境。並非所有函數都是函數文字。例如,它們經常通過另一個功能或方法的「部分應用」來創建(由編譯器自動或透明地編譯或顯式地創建)。 – 2013-02-08 15:46:47

回答

3

如何

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

正如前面所指出的那樣,你的方法需要包含optionalMethodOption值。如果你想避免Option

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

,你可以嘗試以下方法:必須將Option值,因此傳遞給它(ESP避免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") 
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 

您必須只需添加 「有些()」 在你optinal功能

7

錯誤消息非常明確:sampleMethod需要Option,但是您傳遞的是直函數值(未包含在Some中)。

解決這個問題的最簡單的方法是包裝optMethodSome

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 
+0

我認爲重載比使用'Option'作爲函數參數要好得多。 – 2013-02-08 15:34:20

+0

你的意思是隻使用2個重載(一個有參數,一個沒有),而不是3個重載,就像我的答案一樣?如果是這樣的話,那麼在一般情況下,兩種情況之間可能存在足夠的共同行爲,您想將其分解爲單個實現(就像在我的第一個重載中完成所有工作一樣),並且存在足夠的差異'optionalMethod'的默認值(如@ fynn的答案)可能不夠。這很大程度上取決於實際需要。 – 2013-02-08 15:59:40

+2

然後創建一個私有方法來完成這項工作,並採用'Option [Function]',然後通過公共方法調用帶有或不帶'Function'的重載方法。 – 2013-02-08 16:19:47

相關問題