Understanding type inferrence in Scala
I wrote the following simple program:
import java.util.{Set => JavaSet}
import java.util.Collections._
object Main extends App {
def test(set: JavaSet[String]) = ()
test(emptySet()) //fine
test(emptySet) //error
}
DEMO
And was really surprised the the final line test(emptySet)
was not compiled. Why? What is the difference between test(emptySet())
? I thought in Scala we could omit parenthesis freely in such cases.
See Method Conversions in Scala specification:
The following four implicit conversions can be applied to methods which are not applied to some argument list.
Evaluation
A parameterless method m of type => T is always converted to type T by evaluating the expression to which m is bound.
Implicit Application
If the method takes only implicit parameters, implicit arguments are passed following the rules here.
Eta Expansion
Otherwise, if the method is not a constructor, and the expected type pt is a function type (Ts′)⇒T′, eta-expansion is performed on the expression e.
Empty Application
Otherwise, if e has method type ()T, it is implicitly applied to the empty argument list, yielding e().
The one you want is "Empty Application", but it's only applied if none of the earlier conversions are, and in this case "Eta Expansion" happens instead.
EDIT: This was wrong and @Jasper-M's comment is right. No eta-expansion is happening, "Empty Application" is just inapplicable to generic methods currently.
链接地址: http://www.djcxy.com/p/94486.html下一篇: 理解Scala中的类型推理