1

Eclipseワークシート(2.10.1)でこれを試しました:

def a = { println("In a"); 3 }                    //> a: => Int
def b() = { println("In b"); 3 }                  //> b: ()Int
val c = () => { println("In c"); 3 }              //> c  : () => Int = <function0>

def test_type(x: => Int) = x                      //> test_type: (x: => Int)Int

test_type(a)                                      //> In a
                                                  //| res0: Int = 3

b()                                               //> In b
                                                  //| res1: Int = 3
c()                                               //> In c
                                                  //| res2: Int = 3

test_type(b)                                      //> In b
                                                  //| res3: Int = 3
// test_type(c) *** Doesn't compile

私は間違いなく何かが欠けています。abはどう違いcますか?(均一なアクセス原則?)aの「名前による」代替であるように見えるので、 を呼び出すことはできませんが、なぜ型が異なるのでしょうか? と同様に、括弧なしで呼び出すこともできます (つまり、結果に評価されます) 。 )。val a = 3a()bcbbabtest_typecc

もう 1 つの質問ですが、Martin Odersky は彼のオンライン コースで、私が正しければ、次のような任意の匿名関数を() => 3置き換えることができると言っています{ def f() = 3; f }が、これら 2 つの式には異なる型と評価規則があり、最初に関数に評価され、次に -関数の結果、例:

val f2 = { def f() = 3; f }                       //> f2  : Int = 3
4

1 に答える 1

3

Scala がメソッドと関数を異なる方法で扱う場合が多くあります。メソッドはオブジェクトのフィールドを模倣するためによく使用されますが、関数の適用には使用されないため、均一アクセスの原則がメソッドの呼び出しに適用されます。

whilebはtypeのメソッドです、コンパイラが関数型を予期しない限り、()Intコードbは評価時にメソッドを呼び出します。b

は typec関数であるため() => Int、適用はすべてのコンテキストで明示的に行う必要があります。したがって、test_type(c())コンパイルする必要があります。

の「名前による」性質はx: => Int、これらの推論/適用規則には影響しません。パラメータが評価される可能性がある場合にのみ影響します。

scala> object Foo {
     |   def f(): Int = 123
     |   val g: () => Int = () => 123
     | }
defined module Foo

scala> Foo.f
res0: Int = 123

scala> Foo.g
res1: () => Int = <function0>

scala> Foo.g()
res2: Int = 123

scala> (Foo.f: () => Int) // force eta-expansion by explicitly specifying function type
res3: () => Int = <function0>
于 2013-07-14T18:12:28.033 に答える