2014-01-23 246 views
1

我想將函數作爲參數傳遞,但該函數有多個參數(其中之一是函數)。scala - 傳遞函數將另一個函數作爲參數

這裏是我想在一個基本的Python的例子做:

def first(string1, string2, func): 
    func(string1, string2, third) 

def second(string1, string2, func): 
    func(string1, string2) 

def third(string1, string): 
    # operations go here 

first("one", "two", second) 

我在這斯卡拉嘗試是以下幾點:

def first(string1: String, string2: String, func: (Any, Any, Any) => Unit) = { 
    func(string1, string2, func) 
} 
def second(string1: String, string2: String, func: (Any, Any) => Unit) = { 
    func(string1, string2) 
} 

def third(string1: String, string2: String) = { 
    // operations 
} 

def main(args: Array[String]): Unit = { 
    first("one", "two", second) 
} 

我得到一個錯誤試圖通過second轉換爲first,參數數量不足。是否有可能以與Python示例相同的風格實現此功能?

編輯:

我試圖與first("one", "two", second _)更換我的主要方法的機構,它給了我一個類型不匹配錯誤

類型不匹配;發現:(字符串,字符串,(任意,任意,任意)=>單元)=>所需的單位:(任意,任意,任意)=> 單位

任何想法是怎麼回事?

回答

2

你所要做的不是類型安全的。您不能將(String, String, (Any, Any) => Unit) => Unit分配到(Any, Any, Any) => Unit。如果你能,那麼你可以做到以下幾點:

val f = second _ 
val af: (Any, Any, Any) => Unit = f 
af(1, "abc", 5) 

你可以做,如果你更精確地指定類型:

def second(string1: String, string2: String, func: (String, String) => Unit) = { 
    func(string1, string2) 
} 

def third(string1: String, string2: String) = { 
    // operations 
} 

def first(string1: String, string2: String, func: (String, String, (String, String) => Unit) => Unit) = { 
    func(string1, string2, third) 
} 
+0

所以實際的程序我會做有7個函數使用另一個函數作爲參數,它們都嵌套在我的示例代碼的樣式中。我猜想保持Python程序的風格在Scala中並不實際? – kevin

+0

@kevin - 是的,傳遞嵌套的回調會很快變得醜陋。如果你想做一些異步操作,你可以看看期貨。否則爲理解和宏可以用來扁平你的代碼的語法結構。 – Lee

+0

我繼續接受你的回答,因爲它解決了我的問題。是否有任何示例可以指示我使用宏來幫助? – kevin

相關問題