2013-02-14 55 views
1

我是斯卡拉的初學者,請原諒我的無知。斯卡拉foreach與單位通過

這是一個片段,其行爲有點奇怪的理解。

def times(n: Int) = (body: Unit) => (0 until n) foreach(n=>body)

times(5){ println("index") }

的輸出是:索引僅輸出一次。

然而,這一個:

def times(n: Int) = (0 until n) foreach(n=>println("index"))

打印出來的10倍。

回答

2

你的第二個功能應該按預期工作。

你的第一個功能,但是,輸錯,你需要的是這是正確的:

def times(n: Int)(body: => Unit) = (0 until n) foreach(n=>body) 

否則語義如下。 (你的函數:)

def times(n: Int) = (body: Unit) => (0 until n) foreach(n=>body) 

如果你打電話times(n)它會返回一個function這需要Unit作爲參數,運行(0 until n) foreach(n => body)

+1

實際上不應該在咖喱版本中按名稱傳遞函數嗎?像'def times(n:Int)(body:=> Unit)=(0直到n)foreach(n => body)' – 2013-02-14 13:42:19

+0

是的,你是對的。 – Danyel 2013-02-14 13:44:43

+0

是的,在對Scala進行了一些修改之後,我認爲我已經開始理解一些東西......;) – 2013-02-14 13:46:20

3
def times(n: Int) = (body: Unit) => (0 until n) foreach(n=>body) 

方法times創建函數,它Unit並返回Unit

times(5)需要Unit,所以times(5){ println("index") }評估其參數println("index")Unit

評價println("index")n時候,你必須把它作爲像這樣的功能:

def times(n: Int) = (body: Unit => Unit) => (0 until n) foreach(_ => body()) 

用法:

times(5){ _ => println("index") } 

它可以更好地利用parameter groupspass by name

def times(n: Int)(body: => Unit) { (0 until n) foreach(_ => body) } 

用法:

scala> times(5){ println("index") } 
index 
index 
index 
index 
index 
1

首先有一種傾向,認爲Unit意思是「一段代碼」,這是不正確的。 Unit有一個值:()。而已。

所以body值,當你做times(5){ println("index") }{ println("index") },這將是()。如果你五次做(),五次都不會發生。

會發生什麼情況是{ println("index") }被執行,打印內容,然後Unit被返回並被分配到body。就像這樣:

scala> val body = { println("index") } 
index 
body: Unit =() 

scala> (0 until 5) foreach {n => body} 

scala> 

你可以做你想要使用的是什麼了一個用名字參數,在這種情況下,參數將代表計算結果爲Unit的表達,而不是僅僅是Unit的。例如:

def times(n: Int)(body: => Unit) = (0 until n) foreach(n=>body) 

=>前綴參數類型表示參數是通過名稱傳遞。它不會更改的類型,它會更改evalutation strategy(有關詳細信息,請參閱鏈接)。

+0

函數可以接收名字參數;你不得不使用加糖語法,但就是這樣。例如。 '(Monoid [Int] .mappend _):(Int,=> Int)=> Int'。 – 2013-02-16 06:35:14