Scala 3 遷移指南

先決條件

語言

由於 Scala 2.13 和 Scala 3 之間的互通性,因此遷移到 Scala 3 變得很容易,如 相容性參考 頁面中所述。

但是,在將 Scala 2.13 專案移植到 Scala 3 之前,必須符合一些先決條件

  • 它不得依賴尚未移植到 Scala 3 的巨集函式庫。
  • 它不得使用在 Scala 3 中沒有等效項的編譯器外掛程式。
  • 它不得依賴 scala-reflect

以下段落說明如何檢查這些先決條件,以及在未滿足這些條件時可以採取哪些措施。

如果您已準備好進行遷移,您可以直接跳到 sbt 遷移教學課程

巨集依賴項

巨集函式庫是公開巨集方法的 Scala 函式庫。

這些函式庫往往更具表達力,因此在 Scala 2 中廣泛使用。我們可以舉幾個例子

但是 Scala 3 編譯器無法擴充 Scala 2.13 巨集。因此,在跳轉到 Scala 3 之前,您應該確保您的專案不依賴於尚未移植的巨集函式庫。

您可以在 Scala 巨集函式庫 頁面中找到許多巨集函式庫的遷移狀態。希望在您閱讀這些文字時,許多巨集函式庫已經移植。

對於專案中的每個巨集依賴項,您需要將其升級到跨建構版本,也就是在 Scala 2.13 和 Scala 3 上都可用的版本。

我們來看一個快速範例。

必須升級對 "scalatest" %% "scalatest" % "3.0.9" 的依賴項,原因如下

  • scalatest API 基於一些巨集定義。
  • 3.0.9 版本未針對 Scala 3 發布。

我們可以將其升級到版本 3.2.7,該版本在 Scala 2.13 和 Scala 3 中跨發布。

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7"

編譯器外掛程式

Scala 2 編譯器外掛程式與 Scala 3 不相容。

編譯器外掛程式通常透過下列設定之一在 build.sbt 檔案中設定

// build.sbt
libraryDependencies +=
  compilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)

addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)

某些編譯器外掛程式也可能由 sbt 外掛程式自動新增。

您可以透過查看專案的編譯器選項,找出所有已設定的編譯器外掛程式。

sbt:example> show example / Compile / scalacOptions
[info] * -Xplugin:target/compiler_plugins/wartremover_2.13.6-2.4.15.jar
[info] * -Xplugin:target/compiler_plugins/semanticdb-scalac_2.13.6-4.4.18.jar
[info] * -Yrangepos
[info] * -P:semanticdb:targetroot:/example/target/scala-2.13/meta

在上方的範例中,我們可以看到使用了兩個編譯器外掛程式:wartremover 和 semanticdb。對於這些外掛程式中的每個外掛程式,我們需要檢查是否有替代方案,或者我們需要停用它。

以下是使用最頻繁的編譯器外掛程式的替代方案。

SemanticDB

現在已將 SemanticDB 的支援納入 Scala 3 編譯器中

  • -Ysemanticdb 選項會啟動 semanticDB 檔案的產生。
  • -semanticdb-target 選項可用於指定 semanticDB 檔案的輸出目錄。

sbt 能夠透過這個單一設定自動設定 SemanticDB:semanticdbEnabled := true

Scala.js

Scala 3 上的 Scala.js 編譯不再依賴編譯器外掛程式。

若要編譯 Scala.js 專案,您可以使用 sbt-scalajs 外掛程式版本 1.5.0 或更高。

// project/plugins.sbt
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.0")

Scala Native

自 v0.4.3 起,Scala 3 在 Scala Native 中獲得支援。

Scala Native 支援的 Scala 3 最低版本為 3.1.0,因為 Scala 3.0.x 中有致命的阻擋程式。

Kind Projector

-Ykind-projector 選項下,Scala 3 支援 Kind Projector 語法的子集。

此外,我們現在有以下功能,讓 kind-projector 在許多情況下不再需要

您可以在其 專屬頁面 中進一步了解 Kind Projector 移轉。

執行時期反射

scala-reflect 將不會移植到 Scala 3,因為它公開了 Scala 3 中不存在的 Scala 2 編譯器內部元件。

如果您的專案依賴 scala-reflect,或使用 Manifest 類別的執行個體,則無法由 Scala 3 編譯器編譯。若要解決此情況,您可以嘗試使用 Java 反射或 Scala 3 元程式設計功能 重新實作對應的程式碼部分。

如果 scala-reflect 以遞迴方式新增到您的類別路徑中,您可能需要升級帶來它的依賴項。

此頁面的貢獻者