Skip to content

Commit 0a0a43f

Browse files
authored
Add code tabs for _tour/type-inference (#2557)
* Add code tabs for _tour/type-inference * Update type-inference.md * Update type-inference.md * Update type-inference.md * Update type-inference.md * Add code tabs for _tour/type-inference
1 parent 0084465 commit 0a0a43f

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

_tour/type-inference.md

+35
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,70 @@ The Scala compiler can often infer the type of an expression so you don't have t
1212

1313
## Omitting the type
1414

15+
{% tabs type-inference_1 %}
16+
{% tab 'Scala 2 and 3' for=type-inference_1 %}
1517
```scala mdoc
1618
val businessName = "Montreux Jazz Café"
1719
```
20+
{% endtab %}
21+
{% endtabs %}
22+
1823
The compiler can detect that `businessName` is a String. It works similarly with methods:
1924

25+
{% tabs type-inference_2 %}
26+
{% tab 'Scala 2 and 3' for=type-inference_2 %}
2027
```scala mdoc
2128
def squareOf(x: Int) = x * x
2229
```
30+
{% endtab %}
31+
{% endtabs %}
32+
2333
The compiler can infer that the return type is an `Int`, so no explicit return type is required.
2434

2535
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:
2636

37+
{% tabs type-inference_3 class=tabs-scala-version %}
38+
{% tab 'Scala 2' for=type-inference_3 %}
2739
```scala mdoc:fail
2840
def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
2941
```
42+
{% endtab %}
43+
{% tab 'Scala 3' for=type-inference_3 %}
44+
```scala
45+
def fac(n: Int) = if n == 0 then 1 else n * fac(n - 1)
46+
```
47+
{% endtab %}
48+
{% endtabs %}
3049

3150
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.
3251

3352
Here are two examples:
3453

54+
{% tabs type-inference_4 %}
55+
{% tab 'Scala 2 and 3' for=type-inference_4 %}
3556
```scala mdoc
3657
case class MyPair[A, B](x: A, y: B)
3758
val p = MyPair(1, "scala") // type: MyPair[Int, String]
3859

3960
def id[T](x: T) = x
4061
val q = id(1) // type: Int
4162
```
63+
{% endtab %}
64+
{% endtabs %}
4265

4366
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`.
4467

4568
## Parameters
4669

4770
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.
4871

72+
{% tabs type-inference_5 %}
73+
{% tab 'Scala 2 and 3' for=type-inference_5 %}
4974
```scala mdoc
5075
Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8)
5176
```
77+
{% endtab %}
78+
{% endtabs %}
5279

5380
The parameter for map is `f: A => B`. Because we put integers in the `Seq`, the compiler knows that `A` is `Int` (i.e. that `x` is an integer). Therefore, the compiler can infer from `x * 2` that `B` is type `Int`.
5481

@@ -58,14 +85,22 @@ It is generally considered more readable to declare the type of members exposed
5885

5986
Also, type inference can sometimes infer a too-specific type. Suppose we write:
6087

88+
{% tabs type-inference_6 %}
89+
{% tab 'Scala 2 and 3' for=type-inference_6 %}
6190
```scala
6291
var obj = null
6392
```
93+
{% endtab %}
94+
{% endtabs %}
6495

6596
We can't then go on and make this reassignment:
6697

98+
{% tabs type-inference_7 %}
99+
{% tab 'Scala 2 and 3' for=type-inference_7 %}
67100
```scala mdoc:fail
68101
obj = new AnyRef
69102
```
103+
{% endtab %}
104+
{% endtabs %}
70105

71106
It won't compile, because the type inferred for `obj` was `Null`. Since the only value of that type is `null`, it is impossible to assign a different value.

0 commit comments

Comments
 (0)