该示例应用了哪种方法转换?

时间:2014-08-24 17:25:45

标签: scala methods

在scala 6.26.2的规范中,方法有4种转换:

  

MethodConversions

     

以下四个隐式转换可以应用于未应用于某些参数列表的方法。

     
      
  1. 评价即可。类型=>的无参数方法m通过评估m绑定的表达式,T总是转换为类型T.

  2.   
  3. 隐式应用。如果该方法仅采用隐式参数,则遵循§7.2的规则传递隐式参数。

  4.   
  5. Eta扩展。否则,如果方法不是构造函数,并且期望的类型pt是函数类型(Ts')⇒T',则对表达式e执行eta-expansion(§6.26.5)。

  6.   
  7. 清空申请。否则,如果e有方法类型()T,它将隐式应用于空参数列表,产生e()。

  8.   

一些scala代码:

def hello(): String = "abc"

def world1(s: String) = s
def world2(s: => String) = s
def world3(s: () => String) = s

world1(hello)
world2(hello)
world3(hello)

我的问题是,对于world1world2world3,哪个转换规则适用于每个转换规则?

1 个答案:

答案 0 :(得分:3)

def world1(s: String) = s
world1(hello)

空应用程序:hello被评估为hello(),然后作为world1

的参数传递
def world2(s: => String) = s
world2(hello)

Eta-expansion +评估:hello被扩展为一个函数并且懒惰地进行评估。


def world3(s: () => String) = s
world3(hello)

Eta-expansion:hello扩展为Function0[String]


Eta扩展是必要的,因为方法和函数是两个不同的东西,即使scala编译器非常善于隐藏这种差异。

不同之处在于方法是JVM概念,而第一类函数是特定于scala的概念。

你可以在REPL中试试这个。首先,让我们定义一个方法hello

scala> def hello(s: String) = s"hello $s"
hello: (s: String)String


scala> hello.hashCode
<console>:9: error: missing arguments for method hello;
follow this method with `_' if you want to treat it as a partially applied function
              hello.hashCode
              ^

Woops,hello不是一个值(在JVM意义上)!没有哈希码就是证明。

让我们从Function1方法中获得hello

scala> hello _
res10: String => String = <function1>    

scala> (hello _).hashCode
res11: Int = 1710358635

函数是一个值,因此它有一个哈希码。