Skip to content

Commit b4b509f

Browse files
authored
Merge pull request #2511 from benluo/A-First-Look-at-Types-tabs-code
A first look at types tabs code
2 parents 05ad391 + c039e6c commit b4b509f

File tree

1 file changed

+68
-12
lines changed

1 file changed

+68
-12
lines changed

Diff for: _overviews/scala3-book/first-look-at-types.md

+68-12
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ next-page: control-structures
88
---
99

1010

11-
1211
## All values have a type
1312

1413
In Scala, all values have a type, including numerical values and functions.
1514
The diagram below illustrates a subset of the type hierarchy.
1615

1716
<a href="{{ site.baseurl }}/resources/images/scala3-book/hierarchy.svg"><img style="width:100%" src="{{ site.baseurl }}/resources/images/scala3-book/hierarchy.svg" alt="Scala 3 Type Hierarchy"></a>
1817

19-
2018
## Scala type hierarchy
2119

2220
`Any` is the supertype of all types, also called the **top type**.
@@ -42,12 +40,18 @@ If Scala is used in the context of a Java runtime environment, `AnyRef` correspo
4240
In statement-based languages, `void` is used for methods that don’t return anything.
4341
If you write methods in Scala that have no return value, such as the following method, `Unit` is used for the same purpose:
4442

43+
{% tabs unit %}
44+
{% tab 'Scala 2 and 3' for=unit %}
4545
```scala
4646
def printIt(a: Any): Unit = println(a)
4747
```
48+
{% endtab %}
49+
{% endtabs %}
4850

4951
Here’s an example that demonstrates that strings, integers, characters, boolean values, and functions are all instances of `Any` and can be treated just like every other object:
5052

53+
{% tabs any %}
54+
{% tab 'Scala 2 and 3' for=any %}
5155
```scala
5256
val list: List[Any] = List(
5357
"a string",
@@ -59,6 +63,8 @@ val list: List[Any] = List(
5963

6064
list.foreach(element => println(element))
6165
```
66+
{% endtab %}
67+
{% endtabs %}
6268

6369
The code defines a value `list` of type `List[Any]`.
6470
The list is initialized with elements of various types, but each is an instance of `scala.Any`, so we can add them to the list.
@@ -78,6 +84,8 @@ true
7884
As shown above, Scala’s numeric types extend `AnyVal`, and they’re all full-blown objects.
7985
These examples show how to declare variables of these numeric types:
8086

87+
{% tabs anyval %}
88+
{% tab 'Scala 2 and 3' for=anyval %}
8189
```scala
8290
val b: Byte = 1
8391
val i: Int = 1
@@ -86,31 +94,45 @@ val s: Short = 1
8694
val d: Double = 2.0
8795
val f: Float = 3.0
8896
```
97+
{% endtab %}
98+
{% endtabs %}
8999

90100
In the first four examples, if you don’t explicitly specify a type, the number `1` will default to an `Int`, so if you want one of the other data types---`Byte`, `Long`, or `Short`---you need to explicitly declare those types, as shown.
91101
Numbers with a decimal (like 2.0) will default to a `Double`, so if you want a `Float` you need to declare a `Float`, as shown in the last example.
92102

93103
Because `Int` and `Double` are the default numeric types, you typically create them without explicitly declaring the data type:
94104

105+
{% tabs anynum %}
106+
{% tab 'Scala 2 and 3' for=anynum %}
95107
```scala
96108
val i = 123 // defaults to Int
97109
val x = 1.0 // defaults to Double
98110
```
111+
{% endtab %}
112+
{% endtabs %}
99113

100114
In your code you can also append the characters `L`, `D`, and `F` (and their lowercase equivalents) to numbers to specify that they are `Long`, `Double`, or `Float` values:
101115

116+
{% tabs type-post %}
117+
{% tab 'Scala 2 and 3' for=type-post %}
102118
```scala
103119
val x = 1_000L // val x: Long = 1000
104120
val y = 2.2D // val y: Double = 2.2
105121
val z = 3.3F // val z: Float = 3.3
106122
```
123+
{% endtab %}
124+
{% endtabs %}
107125

108126
Scala also has `String` and `Char` types, which you can generally declare with the implicit form:
109127

128+
{% tabs type-string %}
129+
{% tab 'Scala 2 and 3' for=type-string %}
110130
```scala
111131
val s = "Bill"
112132
val c = 'a'
113133
```
134+
{% endtab %}
135+
{% endtabs %}
114136

115137
As shown, enclose strings in double-quotes---or triple-quotes for multiline strings---and enclose a character in single-quotes.
116138

@@ -128,28 +150,32 @@ Those data types and their ranges are:
128150
| Char | 16-bit unsigned Unicode character (0 to 2^16-1, inclusive)<br/>0 to 65,535 |
129151
| String | a sequence of `Char` |
130152

131-
132-
133153
## `BigInt` and `BigDecimal`
134154

135155
When you need really large numbers, use the `BigInt` and `BigDecimal` types:
136156

157+
{% tabs type-bigint %}
158+
{% tab 'Scala 2 and 3' for=type-bigint %}
137159
```scala
138160
val a = BigInt(1_234_567_890_987_654_321L)
139161
val b = BigDecimal(123_456.789)
140162
```
163+
{% endtab %}
164+
{% endtabs %}
141165

142166
Where `Double` and `Float` are approximate decimal numbers, `BigDecimal` is used for precise arithmetic, such as when working with currency.
143167

144168
A great thing about `BigInt` and `BigDecimal` is that they support all the operators you’re used to using with numeric types:
145169

170+
{% tabs type-bigint2 %}
171+
{% tab 'Scala 2 and 3' for=type-bigint2 %}
146172
```scala
147173
val b = BigInt(1234567890) // scala.math.BigInt = 1234567890
148174
val c = b + b // scala.math.BigInt = 2469135780
149175
val d = b * b // scala.math.BigInt = 1524157875019052100
150176
```
151-
152-
177+
{% endtab %}
178+
{% endtabs %}
153179

154180
## Two notes about strings
155181

@@ -163,28 +189,39 @@ Scala strings are similar to Java strings, but they have two great additional fe
163189
String interpolation provides a very readable way to use variables inside strings.
164190
For instance, given these three variables:
165191

192+
{% tabs string-inside1 %}
193+
{% tab 'Scala 2 and 3' for=string-inside1 %}
166194
```scala
167195
val firstName = "John"
168196
val mi = 'C'
169197
val lastName = "Doe"
170198
```
199+
{% endtab %}
200+
{% endtabs %}
171201

172202
You can combine those variables in a string like this:
173203

204+
{% tabs string-inside2 %}
205+
{% tab 'Scala 2 and 3' for=string-inside2 %}
174206
```scala
175207
println(s"Name: $firstName $mi $lastName") // "Name: John C Doe"
176208
```
209+
{% endtab %}
210+
{% endtabs %}
177211

178212
Just precede the string with the letter `s`, and then put a `$` symbol before your variable names inside the string.
179213

180214
To enclose potentially larger expressions inside a string, put them in curly braces:
181215

216+
{% tabs string-inside3 %}
217+
{% tab 'Scala 2 and 3' for=string-inside3 %}
182218
```scala
183219
println(s"2 + 2 = ${2 + 2}") // prints "2 + 2 = 4"
184220
val x = -1
185221
println(s"x.abs = ${x.abs}") // prints "x.abs = 1"
186222
```
187-
223+
{% endtab %}
224+
{% endtabs %}
188225

189226
#### Other interpolators
190227

@@ -193,42 +230,55 @@ If you use an `f` instead of an `s`, you can use `printf`-style formatting synta
193230
Furthermore, a string interpolator is a just special method, and it is possible to define your own.
194231
For instance, some database libraries define the very powerful `sql` interpolator.
195232

196-
197233
### Multiline strings
198234

199235
Multiline strings are created by including the string inside three double-quotes:
200236

237+
{% tabs string-mlines1 %}
238+
{% tab 'Scala 2 and 3' for=string-mlines1 %}
201239
```scala
202240
val quote = """The essence of Scala:
203241
Fusion of functional and object-oriented
204242
programming in a typed setting."""
205243
```
244+
{% endtab %}
245+
{% endtabs %}
206246

207247
One drawback of this basic approach is that the lines after the first line are indented, and look like this:
208248

249+
{% tabs string-mlines2 %}
250+
{% tab 'Scala 2 and 3' for=string-mlines2 %}
209251
```scala
210252
"The essence of Scala:
211253
Fusion of functional and object-oriented
212254
programming in a typed setting."
213255
```
256+
{% endtab %}
257+
{% endtabs %}
214258

215259
When spacing is important, put a `|` symbol in front of all lines after the first line, and call the `stripMargin` method after the string:
216260

261+
{% tabs string-mlines3 %}
262+
{% tab 'Scala 2 and 3' for=string-mlines3 %}
217263
```scala
218264
val quote = """The essence of Scala:
219265
|Fusion of functional and object-oriented
220266
|programming in a typed setting.""".stripMargin
221267
```
268+
{% endtab %}
269+
{% endtabs %}
222270

223271
Now all of the lines are left-justified inside the string:
224272

273+
{% tabs string-mlines4 %}
274+
{% tab 'Scala 2 and 3' for=string-mlines4 %}
225275
```scala
226276
"The essence of Scala:
227277
Fusion of functional and object-oriented
228278
programming in a typed setting."
229279
```
230-
231-
280+
{% endtab %}
281+
{% endtabs %}
232282

233283
## Type casting
234284

@@ -237,27 +287,33 @@ Value types can be cast in the following way:
237287

238288
For example:
239289

290+
{% tabs cast1 %}
291+
{% tab 'Scala 2 and 3' for=cast1 %}
240292
```scala
241293
val b: Byte = 127
242294
val i: Int = b // 127
243295

244296
val face: Char = '☺'
245297
val number: Int = face // 9786
246298
```
299+
{% endtab %}
300+
{% endtabs %}
247301

248302
You can only cast to a type if there is no loss of information. Otherwise, you need to be explicit about the cast:
249303

304+
{% tabs cast2 %}
305+
{% tab 'Scala 2 and 3' for=cast2 %}
250306
```scala
251307
val x: Long = 987654321
252308
val y: Float = x.toFloat // 9.8765434E8 (note that `.toFloat` is required because the cast results in precision loss)
253309
val z: Long = y // Error
254310
```
311+
{% endtab %}
312+
{% endtabs %}
255313

256314
You can also cast a reference type to a subtype.
257315
This will be covered later in the tour.
258316

259-
260-
261317
## `Nothing` and `null`
262318

263319
`Nothing` is a subtype of all types, also called the **bottom type**.

0 commit comments

Comments
 (0)