2013-09-25 2 views
18

私が知っていることに対する具体的な回答を見つけるのは難しいです。 Scalaでブロックがどのように動作するかを理解したいと思います。私はjava/ruby​​のバックグラウンドから来て、scalaはブロックを使用する全く異なる方法を持っているようです。Scalaブロックの理解

次のコードはPlay! Framework websiteです。 アクションが意味論的であることを理解したいと思います。それは、ブロックを受け入れるオブジェクトか関数か、あるいはどちらもそうではありません。

object Application extends Controller { 

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

} 

それが関数である場合は、おそらくそれは、(どのようにScalaは、背後のブロックの周囲を通過ん。その場合には)次のためにシンタックスシュガーです:

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

それともそれは私が「いくつかのScalaの構文ですわからない。

Scalaのソースコードを参照すると、これが背後でどのように機能しているか理解できます。

答えて

21

スカラブロックについては、Rubyブロックではなく、Javaの匿名クラス(Guava関数など)と考える方がよいでしょう。

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

違いはScalaは構文糖の多くを提供することで、あなたにコードの上に書くことができます:あなたはScalaのコードを逆コンパイル場合、実際に言えば、あなたは多かれ少なかれ同じコード(taken from Guava examples)が表示されます

具体的なアクションの例として
val lengthFunction = { string: String => string.length } 

:ここ

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

アクションメソッドを適用すると可能性が高いオブジェクトです。もう一つのスカラ砂糖:言語はFoo(bar)と意味はFoo.apply(bar)と書くことができます。

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

そして署名としてこのようなものを持っている:

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

すでに@yanで言ったように、それはScalaはある次に、you can drop round braces when your call isn't ambiguousは、そう、はい、それは次のように呼ばれました方法は、実際にあります

脱糖呼び出しが

のようになります。結果ねえ、私が作成し、別の関数を受け入れる機能だ 言いにする方法
def index = Action.apply(new AbstractFunction[Result] { 
     def apply() = Ok.apply(views.html.index.apply("...")) 
}) 
8

ここではいくつかのことが起こっています。 Actionは、apply()メソッドを実装するオブジェクトです。オブジェクトを関数として扱うときに呼び出されるものは何ですか。いくつかありますapply()implementations。最初の実装では、by-nameパラメータが使用されています。

スカラーは、「by-name parameters」として知られている概念をサポートしています。これは、それらを参照するコードが実行されたときだけ評価される点を除き、通常のパラメータと似ています。マクロに頼らずに言語の一部であるように見える構造を作成するのに役立ちます。この場合、Ok(..)を囲むブロックは、ブロックの値として最後の値が使用されている通常の文ブロックです。あなたが提供した例は、中括弧なしでもうまくいきます。基本的には、Okのapplyメソッドの結果をActionapplyメソッドに渡すだけです。

apply()の2番目のバージョンは、実際には要求を結果にマップする完全な無名関数をとります。この場合、匿名(または名前付き)関数を渡すことができます。

+0

返信いただきありがとうございます。だから、私が集めていることから、これはAction.apply()のための統語的な砂糖です。砂糖を取り除くと、声明全体はどのように見えますか? – b1nd

+0

あなたが持っているステートメントは本質的に 'Action.apply(Ok.apply(views.html.index("あなたの新しいアプリケーションは準備ができています) "))'です。私が指定したURLの 'apply()'の定義を見ると、パラメータの型の前に矢印があることに気がつきます。これは、上で説明したように、それを「名前による」パラメータにマークするだけです。 (また、by-nameの構文が引数のない無名関数のように見えることは偶然ではありません) – yan

+0

途中でドキュメントを再生するリンクが壊れています。時には、SOパーサーがドル記号を含むリンクを壊すことがあります。 –

関連する問題