val businessName = "Montreux Jazz Café"
businessName: String = "Montreux Jazz Caf\u00e9"
The compiler can detect that
businessName is a String. It works similarly with methods:
def squareOf(x: Int) = x * x
defined function squareOf
The compiler can infer that the return type is an
Int, so no explicit return type is required.
For recursive methods, the compiler is not able to infer a result type. Here is a program which will fail the compiler for this reason:
def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
cmd2.sc:1: recursive method fac needs result type def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) ^Compilation Failed
case class MyPair[A, B](x: A, y: B); val p = MyPair(1, "scala") // type: MyPair[Int, String] def id[T](x: T) = x val q = id(1) // type: Int
defined class MyPair p: MyPair[Int, String] = MyPair(1, "scala") defined function id q: Int = 1
The compiler uses the types of the arguments of
MyPair to figure out what type
B are. Likewise for the type of
The compiler never infers method parameter types. However, in certain cases, it can infer anonymous function parameter types when the function is passed as argument.
Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8)
res3: Seq[Int] = List(2, 6, 8)
The parameter for map is
f: A => B. Because we put integers in the
Seq, the compiler knows that
Int (i.e. that
x is an integer). Therefore, the compiler can infer from
x * 2 that
B is type
It is generally considered more readable to declare the type of members exposed in a public API. Therefore, we recommended that you make the type explicit for any APIs that will be exposed to users of your code.
Also, type inference can sometimes infer a too-specific type. Suppose we write:
var obj = null
obj: Null = null
We can't then go on and make this reassignment:
obj = new AnyRef
cmd5.sc:1: type mismatch; found : Object required: Null val res5 = obj = new AnyRef ^Compilation Failed