在scala 6.26.2的规范中,方法有4种转换:
MethodConversions
以下四个隐式转换可以应用于未应用于某些参数列表的方法。
评价即可。类型=>的无参数方法m通过评估m绑定的表达式,T总是转换为类型T.
隐式应用。如果该方法仅采用隐式参数,则遵循§7.2的规则传递隐式参数。
Eta扩展。否则,如果方法不是构造函数,并且期望的类型pt是函数类型(Ts')⇒T',则对表达式e执行eta-expansion(§6.26.5)。
- 醇>
清空申请。否则,如果e有方法类型()T,它将隐式应用于空参数列表,产生e()。
一些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)
我的问题是,对于world1
,world2
和world3
,哪个转换规则适用于每个转换规则?
答案 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
函数是一个值,因此它有一个哈希码。