2011-12-15 54 views
1

該代碼僅用於說明目的,即它是一個示例不是一個真實的代碼。如何使用yield for multistatement for?

我嘗試這樣做:

val results = for(i <- 1 to 20) 
{ 
    val x = i+1 
    println(x) 
    yield x 
} 

val results = for {i <- 1 to 20; 
    val x = i+1; 
    println(x) 
} 
    yield x 

但這一切工作 - 我需要一臺發電機,定義和聲明 - 這是可能的用收益率做?如果是,那麼正確的語法是什麼?

回答

8

希望這將讓你開始:

val result = for (i <- 1 to 10 if i%2==0) yield { 
    println(i); 
    i 
    } 

這相當於

(1 to 10).filter(_%2==0).map(x => { println(x); x }) 
+0

太棒了,我不知道產量可能是一個結果表達塊。 – greenoldman 2011-12-15 12:42:04

3

你似乎認爲for在Scala是在命令式語言類似for。不是!在幕後,它使用了flatMapfor/yield語法的第一部分中的每個表達式都必須具有某種形式。如果我沒有弄錯,它必須是一個任務(限制爲val,也許)或<-表達式。你可以破解它得到你想要的:

for { 
    i <- 1 to 20 
    val x = i + 1 
    _ <- {println(x); List(1)} 
} yield x 

但這是非常可怕的。正如Jamil所示,黑客yield也是一種可能性,雖然也非常可怕。

問題是,你到底想要完成什麼? foreach最適用於副作用的循環代碼:

(1 to 10) foreach { i => 
    val x = i+1 
    println(x) 
} 

map最適用於生產相同長度的新名單:

(1 to 10) map (i => i + 1) 

這是相當不尋常的,而且有點難看,想同時做兩個。

+0

謝謝,但請注意2件事。隨着foreach你沒有得到任何結果,並與地圖你沒有得到任何聲明(它是可以修復的)。我試圖完成什麼?它取決於任務 - 它簡化爲這三個:發生器+定義+語句,產生新的序列。問題是優雅 - 對我來說,更優雅的地圖,這就是爲什麼我嘗試使用+收益。 – greenoldman 2011-12-15 12:45:28