在 GitHub 上編輯此頁面

主要方法

Scala 3 提供定義可從命令列呼叫的程式的全新方式:方法上的 @main 注解會將此方法轉換為可執行程式。範例

@main def happyBirthday(age: Int, name: String, others: String*) =
  val suffix =
    age % 100 match
    case 11 | 12 | 13 => "th"
    case _ =>
      age % 10 match
        case 1 => "st"
        case 2 => "nd"
        case 3 => "rd"
        case _ => "th"
  val bldr = new StringBuilder(s"Happy $age$suffix birthday, $name")
  for other <- others do bldr.append(" and ").append(other)
  bldr.toString

這將產生一個主程式 happyBirthday,可像這樣呼叫

> scala happyBirthday 23 Lisa Peter
Happy 23rd birthday, Lisa and Peter

帶有 @main 注解的方法可以在頂層或靜態可存取的物件中撰寫。程式名稱在每種情況下都是方法名稱,不含任何物件前置字。@main 方法可以有任意數量的參數。對於每個參數類型,都必須有一個 scala.util.CommandLineParser.FromString[T] 類型類別的實例,用於將引數字串轉換為所需的參數類型 T。主方法的參數清單可以結束於重複參數,然後取得命令列上提供的其他所有引數。

@main 方法實作的程式會檢查命令列上是否有足夠的引數來填入所有參數,以及引數字串是否可轉換為所需的類型。如果檢查失敗,程式會終止並顯示錯誤訊息。

範例

> scala happyBirthday 22
Illegal command line after first argument: more arguments expected

> scala happyBirthday sixty Fred
Illegal command line: java.lang.NumberFormatException: For input string: "sixty"

Scala 編譯器會從 @main 方法 f 產生程式,如下所示

  • 它在找到 @main 方法的封裝中建立一個名為 f 的類別
  • 這個類別有一個靜態方法 main,具有通常的簽章。它將 Array[String] 作為引數,並傳回 Unit
  • 產生的 main 方法會呼叫方法 f,並使用 scala.util.CommandLineParser 物件中的方法轉換引數。

例如,上述的 happyBirthday 方法會產生與下列類別等效的額外程式碼

final class happyBirthday:
  import scala.util.CommandLineParser as CLP
  <static> def main(args: Array[String]): Unit =
    try
      happyBirthday(
        CLP.parseArgument[Int](args, 0),
        CLP.parseArgument[String](args, 1),
        CLP.parseRemainingArguments[String](args, 2))
    catch
      case error: CLP.ParseError => CLP.showError(error)

注意:上述的 <static> 修飾詞表示 main 方法會產生為類別 happyBirthday 的靜態方法。它不適用於 Scala 中的使用者程式。正規的「靜態」成員會使用物件在 Scala 中產生。

@main 方法是建議用於產生可以在 Scala 3 中從命令列呼叫的程式的方案。它們取代了先前將程式寫為具有特殊 App 父類別的物件的方案。在 Scala 2 中,happyBirthday 也可以像這樣寫

object happyBirthday extends App:
  // needs by-hand parsing of arguments vector
  ...

先前依賴於「神奇」DelayedInit 特質的 App 功能不再可用。 App 目前仍以有限的形式存在,但它不支援命令列引數,而且未來將會被棄用。如果程式需要在 Scala 2 和 Scala 3 之間進行交叉建置,建議使用具有 Array[String] 引數的明確 main 方法。