2014-09-26 22 views
1

在下面的代碼:斯卡拉的外部和內部函數參數的目的是什麼?

def product(f: Int => Int)(a:Int, b:Int): Int = 
    if (a > b) 1 
    else f(a) * product(f)(a + 1, b) 

參數ab傳遞給內部函數,但你可以準確地寫相同的函數定義,像這樣:

def product(f: Int => Int, a:Int, b:Int): Int = 
    if (a > b) 1 
    else f(a) * product(f, a + 1, b) 

那麼目的是什麼分離參數?換句話說,爲什麼這樣做:

(f: Int => Int)(a:Int, b:Int) 

時,你可以更清楚地寫:

(f: Int => Int, a:Int, b:Int) 
+0

事實上它們不是「外部」或「內部」,可以有任意數量的參數列表:)'f(a:Int)(b:Double)(c:String)(d:Long)'是過時合法的。 – 2014-09-26 08:34:04

回答

0

這取決於是否有隱含參數(不能用普通的人正確地混合).. 。

def foo(i: Int)(implicit p: P): Foo 

...你怎麼稱呼它的方式......

def foo1(a: Int)(b: Int => Boolean): Boolean 
foo1(9) { i => false } 

def foo2(a: Int, b: Int => Boolean): Boolean 
foo2(9, { i => false }) 
3

多個參數列表的另一個特徵是局部應用:

def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c 

val g: Int => Int => Int = sum3(10) _ 
val h: Int => Int  = g(20) 
val r: Int    = h(30) // 10 + 20 + 30 = 60 

可以部分地應用一個函數,將獲得另一功能是相當於原來的一個,但與固定的參數之一。 _之後sum3(10)是必需的,因爲sum3是一種方法,而不是函數,並且_將方法轉換爲函數。

,這是非常有用的,當您使用高階函數:

def adder(x: Int)(y: Int) = x + y 

Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14) 

當部分施加的方法/函數被用作更高階的呼叫的參數,不需要_,和語法變得非常簡潔。

+0

謝謝 - 你上面的'f(10)'調用是否應該是'sum3(10)'? – 2014-09-26 09:06:56

+0

@jimmy_terra,是的,你是對的,謝謝! – 2014-09-26 13:57:46

1

此功能的另一個用例是,如果你想創建一個看起來像它內置到Scala編程語言本身的控制結構。

例如,可以寫命名times的控制結構,其幫我通過以下方法定義完全相同n倍執行的代碼塊:

// since block is call by name, it will not be evaluate when you call it. 
def times(n: Int)(block: => Any): Unit = { 
    for (i <- 0 until n) { 
    block // evaluate(execute) block 
    } 
} 

// Now I can use the times method like a control structure 
times(5) { 
    println("Hello World"); 
} 
+0

我喜歡scala的這個特性。 – sunrize920 2014-09-29 13:15:20