2014-09-30 55 views
1

我有一套它們都具有一個共同的返回類型的功能,但不同的數量和類型的參數,例如:是否有可能推遲使用不同數量/類型的參數評估函數文字?

def find(id: Int): MyVal = {} 
def like(part: String, max: Int): MyVal = {} 
def first(): MyVal = {} 

所有這些都需要通過一個共同的驗證程序,而且我會喜歡做的是到該邏輯封裝成一個單一的功能,然後採用任何上述方法的(和其他有同樣返回類型)作爲附加參數:

def checkAndEvaluate(token: String, func:() => MyVal): MyVal = { 
    validateToken(token) match { 
     case Pass => func() 
     case Fail => // Do some error handling 
    } 
} 

換句話說,我想傳遞函數文字,連同他們需要的參數,然後只讓他們在驗證通過時評估來自內部的接收功能。

這是可能的斯卡拉做的,如果是這樣,這將是實現它的首選方式?

回答

4

你不需要使用function可言,你需要的是斯卡拉參數call-by-nameMore about call-by-name parameter

一個簡單的例子:

scala> def invoke(id: Int): Int = { println("invoked"); 0 } 
invoke: (id: Int)Int 

scala> def run(x : Int, i: => Int): Int = x match { 
    | case 0 => i 
    | case 1 => -1 
    | } 
run: (x: Int, i: => Int)Int 

scala> run(0, invoke(100)) 
invoked 
res2: Int = 0 

scala> run(1, invoke(100)) 
res3: Int = -1 

根據您的代碼:

scala> def find(id: Int): Int = 0 
find: (id: Int)Int 

scala> def like(part: String, max: Int): Int = 1 
like: (part: String, max: Int)Int 

scala> def first(): Int = 2 
first:()Int 

scala> def checkAndEval(token: String, lazyEval : => Int): Int = token.size match { 
    | case 0 => lazyEval 
    | case _ => -1 
    | } 
checkAndEval: (token: String, lazyEval: => Int)Int 

scala> checkAndEval("", like("xxx", 0)) 
res0: Int = 1 

scala> checkAndEval("err", like("xxx", 0)) 
res1: Int = -1 
+0

我喜歡你的方法,它的工作原理,但是,我不是scala中的call-by-name語義的粉絲,因爲當你調用函數時,你不知道它發生了什麼,只是在函數中定義。在生產代碼中出現了幾次這樣的問題,因爲懶惰不是很明顯。這更簡潔,我很欣賞:) +1 – Noah 2014-09-30 15:18:02

0

這是很容易在斯卡拉做的,這裏有一個例子:

checkAndEvaluate("token",() => find(1)) 
    checkAndEvaluate("token",() => like("like", 1)) 
    checkAndEvaluate("token",() => first()) 

的功能都將被調用,直到調用func(),如果你調用它。

相關問題