Skip to content

Commit 574cd67

Browse files
committed
Rewrote local type inference tour
1 parent 919471a commit 574cd67

File tree

1 file changed

+19
-27
lines changed

1 file changed

+19
-27
lines changed

tutorials/tour/_posts/2017-02-13-local-type-inference.md

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,41 @@ categories: tour
99
num: 29
1010
next-page: operators
1111
previous-page: polymorphic-methods
12+
prerequisite-knowledge: unified-types, generic-classes
1213
---
13-
Scala has a built-in type inference mechanism which allows the programmer to omit certain type annotations. It is, for instance, often not necessary in Scala to specify the type of a variable, since the compiler can deduce the type from the initialization expression of the variable. Also return types of methods can often be omitted since they correspond to the type of the body, which gets inferred by the compiler.
14+
The Scala compiler can often infer the type of a value so you don't have to declare it explicitly. You'll often see this with variables and return types.
1415

15-
Here is an example:
16-
17-
```tut
18-
object InferenceTest1 extends App {
19-
val x = 1 + 2 * 3 // the type of x is Int
20-
val y = x.toString() // the type of y is String
21-
def succ(x: Int) = x + 1 // method succ returns Int values
22-
}
16+
## Omitting the type
17+
```
18+
val businessName = "Montreux Jazz Café"
19+
```
20+
The compiler can detect that `businessName` is a String. It works similarly with methods:
2321
```
22+
def squareOf(x: Int) = x * x
23+
```
24+
The compiler can infer that the return type is an int so no return type is required.
2425

2526
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:
2627

2728
```tut:fail
28-
object InferenceTest2 {
29-
def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
30-
}
29+
def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
3130
```
3231

3332
It is also not compulsory to specify type parameters when [polymorphic methods](polymorphic-methods.html) are called or [generic classes](generic-classes.html) are instantiated. The Scala compiler will infer such missing type parameters from the context and from the types of the actual method/constructor parameters.
3433

35-
Here is an example which illustrates this:
36-
34+
Here are two examples:
3735
```
3836
case class MyPair[A, B](x: A, y: B);
39-
object InferenceTest3 extends App {
40-
def id[T](x: T) = x
41-
val p = MyPair(1, "scala") // type: MyPair[Int, String]
42-
val q = id(1) // type: Int
43-
}
44-
```
45-
46-
The last two lines of this program are equivalent to the following code where all inferred types are made explicit:
37+
val p = MyPair(1, "scala") // type: MyPair[Int, String]
4738
39+
def id[T](x: T) = x
40+
val q = id(1) // type: Int
4841
```
49-
val x: MyPair[Int, String] = MyPair[Int, String](1, "scala")
50-
val y: Int = id[Int](1)
51-
```
42+
The compiler uses the types of the arguments of `MyPair` to figure out what type `A` and `B` are. Likewise for the type of `x`.
43+
44+
## When not to rely on type inference
5245

53-
In some situations it can be quite dangerous to rely on Scala's type inference mechanism as the following program shows:
46+
It is generally considered more readable to declare the type of members exposed in a public API. Also, in some situations it can be quite dangerous to rely on Scala's type inference mechanism as the following program shows:
5447

5548
```tut:fail
5649
object InferenceTest4 {
@@ -60,4 +53,3 @@ object InferenceTest4 {
6053
```
6154

6255
This program does not compile because the type inferred for variable `obj` is `Null`. Since the only value of that type is `null`, it is impossible to make this variable refer to another value.
63-

0 commit comments

Comments
 (0)