2013-09-25 81 views
18

我很難找到具體的答案,我知道什麼是微不足道的。我想了解塊在Scala中的工作原理。我來自java/ruby​​背景,看起來scala具有完全不同的使用塊的方式。瞭解斯卡拉塊

以下代碼來自Play! Framework website。我想了解什麼動作是語義。它是一個接受一個塊的對象或函數,或者兩者都不是。

object Application extends Controller { 

    def index = Action { 
    Ok(views.html.index("Your new application is ready.")) 
    } 

} 

如果它是一個功能,也許這句法糖以下(在這種情況下如何斯卡拉繞過幕後塊):

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

或者是一些斯卡拉語法我米不知道。

任何對Scala源代碼的引用都會幫助我理解這是如何在幕後工作的。

回答

21

你最好把scala塊當作java匿名類(比如Guava Functions)而不是ruby塊。其實說起來,如果你反編譯Scala代碼,你會看到更多或更少相同的代碼(taken from Guava examples):

Function<String, Integer> lengthFunction = new Function<String, Integer>() { 
    public Integer apply(String string) { 
    return string.length(); 
    } 
}; 

不同的是,斯卡拉提供了很多語法糖,讓你寫上面的代碼爲:

val lengthFunction = { string: String => string.length } 

作爲一個具體的操作實例:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

這裏動作是與應用方法可能對象。另一個scala糖:語言允許你寫Foo(bar)並且意味着Foo.apply(bar)。接下來,you can drop round braces when your call isn't ambiguous,所以是的,它實際上是一家名爲得到了類似的方法:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
}) 

而且有這樣的事情作爲簽名:

object Action { 
    def apply(block: => Result) = ??? 
} 

正如已經@yan說,這是斯卡拉辦法說嘿,我接受,產生另一個函數的函數結果

脫調用看起來像

def index = Action.apply(new AbstractFunction[Result] { 
     def apply() = Ok.apply(views.html.index.apply("...")) 
}) 
8

這裏有一些事情正在進行。 Action是一個實現apply()方法的對象,將對象作爲函數處理時會調用什麼。有幾個apply()implementations。第一個實現使用by-name參數。

Scala支持一種名爲'by-name parameters'的概念,它與普通參數一樣,除了只在執行引用它們的代碼時才進行評估。他們幫助創建看起來像他們是語言的一部分,而不訴諸宏的結構。在這種情況下,圍繞Ok(..)的塊只是一個常規的語句塊,最後一個值用作塊的值。你提供的例子不需要大括號就可以工作。你基本上只是將Ok的apply方法的結果傳遞給Actionapply方法。

apply()的第二個版本確實需要將請求映射到結果的完整匿名函數。在這種情況下,您可以傳遞一個匿名(或命名)函數。

+0

感謝您的回覆。所以從我收集的信息來看,這是Action.apply()的合成糖。除去糖,整個陳述會是什麼樣子? – b1nd

+0

這個聲明基本上是'Action.apply(Ok.apply(views.html.index(「Your new application is ready。」)))'。如果你在我提供的URL中查看'apply()'的定義,你會發現在參數類型之前有一個箭頭。這只是標誌着一個'按名稱'參數,如上所述。 (另外,並非巧合的是,名稱的語法看起來像沒有參數的匿名函數) – yan

+0

鏈接播放文檔被打破。偶爾,SO解析器會弄亂包含美元符號的鏈接。 –