Scala 3 — 書籍

類型簡介

語言

所有值都有類型

在 Scala 中,所有值都有類型,包括數字值和函式。下方的圖表說明了類型階層的子集。

Scala 3 Type Hierarchy

Scala 類型階層

Any 是所有類型的超類型,也稱為頂層類型。它定義了某些通用方法,例如 equalshashCodetoString

頂層類型 Any 有子類型 Matchable,用於標記我們可以執行模式比對的所有類型。保證屬性呼叫「參數性」非常重要。我們在此不深入探討,但總而言之,表示我們無法對類型為 Any 的值進行模式比對,只能對 Matchable 的子類型的值進行模式比對。 參考文件 包含有關 Matchable 的更多資訊。

Matchable 有兩個重要的子類型:AnyValAnyRef

AnyVal 代表值類型。有幾個預定義的值類型,而且它們不可為空:DoubleFloatLongIntShortByteCharUnitBooleanUnit 是一種不帶有有意義資訊的值類型。Unit 有一個實例,我們可以稱之為:()

AnyRef 代表參考類型。所有非值類型都被定義為參考類型。Scala 中的每個使用者定義類型都是 AnyRef 的子類型。如果 Scala 用於 Java 執行時間環境中,AnyRef 對應於 java.lang.Object

在基於語句的語言中,void 用於不傳回任何內容的方法。如果你在 Scala 中撰寫沒有傳回值的方法,例如以下方法,Unit 用於相同目的

def printIt(a: Any): Unit = println(a)

以下範例說明字串、整數、字元、布林值和函式都是 Any 的實例,而且可以像其他物件一樣處理

val list: List[Any] = List(
  "a string",
  732,  // an integer
  'c',  // a character
  '\'', // a character with a backslash escape
  true, // a boolean value
  () => "an anonymous function returning a string"
)

list.foreach(element => println(element))

此程式碼定義一個 List[Any] 類型的值 list。此清單初始化為各種類型的元素,但每個元素都是 scala.Any 的實例,所以我們可以將它們新增到清單中。

以下是程式的輸出

a string
732
c
'
true
<function>

Scala 的「值類型」

如上所示,Scala 的數字類型延伸 AnyVal,而且它們都是完整的物件。這些範例說明如何宣告這些數字類型的變數

val b: Byte = 1
val i: Int = 1
val l: Long = 1
val s: Short = 1
val d: Double = 2.0
val f: Float = 3.0

在頭四個範例中,如果你沒有明確指定類型,數字 1 預設為 Int,因此如果你想要其他資料類型(ByteLongShort),你需要明確宣告這些類型,如下所示。帶有小數點的數字(例如 2.0)預設為 Double,因此如果你想要 Float,你需要宣告 Float,如下一個範例所示。

由於 IntDouble 是預設數字類型,你通常會在沒有明確宣告資料類型的情況下建立它們。

val i = 123   // defaults to Int
val x = 1.0   // defaults to Double

在你的程式碼中,你也可以附加字元 LDF(及其小寫等效字元)到數字,以指定它們是 LongDoubleFloat 值。

val x = 1_000L   // val x: Long = 1000
val y = 2.2D     // val y: Double = 2.2
val z = -3.3F    // val z: Float = -3.3

你也可以使用十六進位表示法來格式化整數(通常是 Int,但也可以支援 L 字尾,以指定它們是 Long)。

val a = 0xACE    // val a: Int = 2766
val b = 0xfd_3aL // val b: Long = 64826

Scala 支援許多不同的方式來格式化相同的浮點數,例如:

val q = .25      // val q: Double = 0.25
val r = 2.5e-1   // val r: Double = 0.25
val s = .0025e2F // val s: Float = 0.25

Scala 也有 StringChar 類型,你通常可以使用隱含形式來宣告它們。

val s = "Bill"
val c = 'a'

如所示,用雙引號將字串括起來(或用三引號表示多行字串),並用單引號將字元括起來。

這些資料類型及其範圍如下:

資料類型 可能值
布林 truefalse
位元組 8 位元有號二補數整數(-2^7 至 2^7-1,包含)
-128 至 127
短整數 16 位元有號二補數整數(-2^15 至 2^15-1,包含)
-32,768 至 32,767
整數 32 位元二補數整數(-2^31 至 2^31-1,包含)
-2,147,483,648 至 2,147,483,647
長整數 64 位元二補數整數(-2^63 至 2^63-1,包含)
(-2^63 到 2^63-1,包含)
浮點數 32 位元 IEEE 754 單精度浮點數
1.40129846432481707e-45 到 3.40282346638528860e+38
雙精度浮點數 64 位元 IEEE 754 雙精度浮點數
4.94065645841246544e-324 到 1.79769313486231570e+308
字元 16 位元無符號 Unicode 字元 (0 到 2^16-1,包含)
0 到 65,535
字串 Char 的序列

字串

Scala 字串類似於 Java 字串,但與 Java 不同(至少在 Java 15 之前),使用三個引號可以輕鬆建立多行字串

val quote = """The essence of Scala:
               Fusion of functional and object-oriented
               programming in a typed setting."""

這種基本方法的一個缺點是,第一行之後的行會縮排,如下所示

"The essence of Scala:
               Fusion of functional and object-oriented
               programming in a typed setting."

如果間距很重要,請在第一行之後的所有行前面加上 | 符號,並在字串之後呼叫 stripMargin 方法

val quote = """The essence of Scala:
               |Fusion of functional and object-oriented
               |programming in a typed setting.""".stripMargin

現在所有行都在字串內靠左對齊

"The essence of Scala:
Fusion of functional and object-oriented
programming in a typed setting."

Scala 字串還支援強大的字串內插方法,我們將在 下一章 中討論。

BigIntBigDecimal

當您需要非常大的數字時,請使用 BigIntBigDecimal 類型

val a = BigInt(1_234_567_890_987_654_321L)
val b = BigDecimal(123_456.789)

其中 DoubleFloat 是近似十進位數,BigDecimal 用於精確運算,例如處理貨幣時。

BigIntBigDecimal 的一個優點是,它們支援您習慣於使用數字類型的所有運算子

val b = BigInt(1234567890)   // scala.math.BigInt = 1234567890
val c = b + b                // scala.math.BigInt = 2469135780
val d = b * b                // scala.math.BigInt = 1524157875019052100

類型轉換

值類型可以透過以下方式轉換:Scala 類型階層

例如

val b: Byte = 127
val i: Int = b  // 127

val face: Char = '☺'
val number: Int = face  // 9786

只有在沒有資訊遺失的情況下,您才能轉換為某個類型。否則,您需要明確說明轉換

val x: Long = 987654321
val y: Float = x.toFloat  // 9.8765434E8 (note that `.toFloat` is required because the cast results in precision loss)
val z: Long = y  // Error

您也可以將參考類型轉換為子類型。這將在後面的導覽中介紹。

Nothingnull

Nothing 是所有類型的子類型,也稱為底部類型。沒有任何值具有類型 Nothing。常見的用途是表示非終止,例如引發的例外、程式結束或無限迴圈,也就是說,它是沒有評估為值的運算式類型,或是不正常返回的方法。

Null 是所有參考類型的子類型(也就是 AnyRef 的任何子類型)。它有一個由關鍵字字面值 null 識別的單一值。目前,使用 null 被認為是不良習慣。它應該主要用於與其他 JVM 語言的互通性。一個選擇加入的編譯器選項會變更 Null 的狀態,以修正與其使用相關的警告。此選項可能會在未來的 Scala 版本中成為預設值。您可以 在此進一步了解它。

在此同時,幾乎不應該在 Scala 程式碼中使用 null。替代 null 的方法會在本手冊的 函式程式設計章節API 文件 中討論。

此頁面的貢獻者