Scala - 基本語法



如果你對Java有很好的理解,那麼學習Scala會非常容易。Scala和Java之間最大的語法區別在於,Scala的語句結尾分號';'是可選的。

當我們考慮一個Scala程式時,它可以定義為一個透過呼叫彼此方法進行通訊的物件集合。讓我們簡要了解一下類、物件、方法和例項變數的含義。

  • 物件 - 物件具有狀態和行為。物件是類的例項。例如 - 狗具有狀態 - 顏色、名字、品種以及行為 - 搖尾巴、吠叫和吃東西。

  • - 類可以定義為描述與類相關的行為/狀態的模板/藍圖。

  • 方法 - 方法基本上是一種行為。一個類可以包含許多方法。在方法中編寫邏輯,操作資料並執行所有操作。

  • 欄位 - 每個物件都有自己唯一的一組例項變數,這些變數稱為欄位。物件的 state 是透過分配給這些欄位的值建立的。

  • 閉包 - 閉包是一個函式,其返回值取決於在此函式外部宣告的一個或多個變數的值。

  • 特質 - 特質封裝了方法和欄位定義,然後可以透過將它們混合到類中來重用它們。特質用於透過指定支援方法的簽名來定義物件型別。

第一個Scala程式

我們可以透過兩種模式執行Scala程式:一種是互動模式,另一種是指令碼模式

互動模式

開啟命令提示符並使用以下命令開啟Scala。

\>scala

如果你的系統中安裝了Scala,則會顯示以下輸出:

Welcome to Scala version 2.9.0.1
Type in expressions to have them evaluated.
Type :help for more information.

在Scala提示符的右側鍵入以下文字,然後按Enter鍵:

scala> println("Hello, Scala!");

它將產生以下結果:

Hello, Scala!

指令碼模式

使用以下說明以指令碼模式編寫Scala程式。開啟記事本並將以下程式碼新增到其中。

示例

object HelloWorld {
   /* This is my first java program.  
   * This will print 'Hello World' as the output
   */
   def main(args: Array[String]) {
      println("Hello, world!") // prints Hello World
   }
}

將檔案另存為 - HelloWorld.scala

開啟命令提示符視窗並轉到儲存程式檔案的目錄。'scalac' 命令用於編譯 Scala 程式,它將在當前目錄中生成一些類檔案。其中一個將被稱為 HelloWorld.class。這是一個將在 Java 虛擬機器 (JVM) 上使用 'scala' 命令執行的位元組碼。

使用以下命令編譯並執行你的Scala程式。

\> scalac HelloWorld.scala
\> scala HelloWorld

輸出

Hello, World!

基本語法

以下是Scala程式設計中的基本語法和編碼約定。

  • 大小寫敏感 - Scala 區分大小寫,這意味著識別符號 Hellohello 在 Scala 中具有不同的含義。

  • 類名 - 對於所有類名,第一個字母應為大寫。如果使用多個單詞來構成類名,則每個內部單詞的第一個字母應為大寫。

    示例 - class MyFirstScalaClass。

  • 方法名 - 所有方法名都應以小寫字母開頭。如果使用多個單詞來構成方法名,則每個內部單詞的第一個字母應為大寫。

    示例 - def myMethodName()

  • 程式檔名 - 程式檔名應與物件名完全匹配。儲存檔案時,應使用物件名儲存(記住 Scala 區分大小寫),並在名稱末尾附加 '.scala'。(如果檔名和物件名不匹配,則程式將無法編譯)。

    示例 - 假設 'HelloWorld' 是物件名。則檔案應儲存為 'HelloWorld.scala'。

  • def main(args: Array[String]) - Scala 程式處理從 main() 方法開始,這是每個 Scala 程式的必備部分。

Scala 識別符號

所有 Scala 元件都需要名稱。用於物件、類、變數和方法的名稱稱為識別符號。關鍵字不能用作識別符號,識別符號區分大小寫。Scala 支援四種類型的識別符號。

字母數字識別符號

字母數字識別符號以字母或下劃線開頭,後面可以跟其他字母、數字或下劃線。'$' 字元是 Scala 中的保留關鍵字,不應在識別符號中使用。

以下是合法的字母數字識別符號

age, salary, _value,  __1_value

以下是非法的識別符號

$salary, 123abc, -salary

運算子識別符號

運算子識別符號由一個或多個運算子字元組成。運算子字元是可列印的 ASCII 字元,例如 +、:、?、~ 或 #。

以下是合法的運算子識別符號:

+ ++ ::: <?> :>

Scala 編譯器將在內部“混淆”運算子識別符號,將其轉換為具有嵌入式 $ 字元的合法 Java 識別符號。例如,識別符號 :-> 將在內部表示為 $colon$minus$greater。

混合識別符號

混合識別符號由一個字母數字識別符號組成,後面跟一個下劃線和一個運算子識別符號。

以下是合法的混合識別符號:

unary_+,  myvar_=

這裡,unary_+ 用作方法名定義了一元 + 運算子,myvar_= 用作方法名定義了一個賦值運算子(運算子過載)。

文字識別符號

文字識別符號是用反引號 (` . . . ` )括起來的任意字串。

以下是合法的文字識別符號:

`x` `<clinit>` `yield`

Scala 關鍵字

以下列表顯示了 Scala 中的保留字。這些保留字不能用作常量或變數或任何其他識別符號名稱。

abstract case catch class
def do else extends
false final finally for
forSome if implicit import
lazy match new Null
object override package private
protected return sealed super
this throw trait Try
true type val var
while with yield  
- : = =>
<- <: <% >:
# @

Scala 註釋

Scala 支援單行和多行註釋,與 Java 非常相似。多行註釋可以巢狀,但必須正確巢狀。Scala 編譯器會忽略任何註釋中可用的所有字元。

object HelloWorld {
   /* This is my first java program.  
    * This will print 'Hello World' as the output
    * This is an example of multi-line comments.
    */
   def main(args: Array[String]) {
      // Prints Hello World
      // This is also an example of single line comment.
      println("Hello, world!") 
   }
}

空行和空格

僅包含空格(可能帶有註釋)的行稱為空行,Scala 完全忽略它。可以使用空格字元和/或註釋分隔標記。

換行符

Scala 是一種面向行的語言,其中語句可以用分號 (;) 或換行符結束。語句末尾的分號通常是可選的。如果語句單獨出現在一行上,則可以鍵入一個,但不必鍵入。另一方面,如果你在一行上編寫多個語句,則需要分號。以下語法是多個語句的用法。

val s = "hello"; println(s)

Scala 包

包是一個命名的程式碼模組。例如,Lift 實用程式包是 net.liftweb.util。包宣告是原始檔中的第一行非註釋行,如下所示:

package com.liftcode.stuff

可以匯入 Scala 包,以便可以在當前編譯範圍內引用它們。以下語句匯入 scala.xml 包的內容:

import scala.xml._

你可以匯入單個類和物件,例如,來自 scala.collection.mutable 包的 HashMap:

import scala.collection.mutable.HashMap

你可以從單個包中匯入多個類或物件,例如,來自 scala.collection.immutable 包的 TreeMap 和 TreeSet:

import scala.collection.immutable.{TreeMap, TreeSet}

應用動態

一個標記特質,啟用動態呼叫。此特質的例項 x 允許針對任意方法名稱 meth 和引數列表 args 進行方法呼叫 x.meth(args),以及針對任意欄位名稱 field 進行欄位訪問 x.field。此功能是在 Scala-2.10 中引入的。

如果 x 本身不支援呼叫(即型別檢查失敗),則會根據以下規則重寫它:

foo.method("blah") ~~> foo.applyDynamic("method")("blah")
foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah"))
foo.method(x = 1, 2) ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2))
foo.field ~~> foo.selectDynamic("field")
foo.varia = 10 ~~> foo.updateDynamic("varia")(10)
foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13)
foo.arr(10) ~~> foo.applyDynamic("arr")(10)
廣告