Scala基礎教程 -- 基礎
2 基礎
2.1 表示式
表示式是可計算的語句。
1 + 1
你可以使用println來輸出表達式的結果。
println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!
常量(Values) 你可以使用val關鍵字來給表示式的結果命名。
val x = 1 + 1
println(x) // 2
對於結果比如這裡的x的命名,被稱為常量(values)。引用一個常量(value)不會再次計算。 常量(values)不能重新被賦值。
x = 3 // This does not compile.
常量(values)的型別可以被推斷,或者你也可以顯示地宣告型別,例如:
val x: Int = 1 + 1
注意下,在識別符號x的後面、型別宣告Int的前面,還需要一個冒號:。 變數(Variables) 除了可以重新賦值,變數和常量類似。你可以使用var關鍵字來定義一個變數。
var x = 1 + 1
x = 3 // This compiles because "x" is declared with the "var" keyword.
println(x * x) // 9
和常量一樣,你可以顯示地宣告型別:
var x: Int = 1 + 1
2.2 程式碼塊(Blocks)
你可以組合幾個表示式,並且用{}包圍起來。我們稱之為程式碼塊(block)。 程式碼塊中最後一個表示式的結果,也正是整個塊的結果。
println({
val x = 1 + 1
x + 1
}) // 3
2.3 函式
函式是帶有引數的表示式。 你可以定義一個匿名函式(即沒有名字),來返回一個給定整數加一的結果。
(x: Int) => x + 1
=>的左邊是引數列表,右邊是一個包含引數的表示式。 你也可以給函式命名。
val addOne = (x: Int) => x + 1
println(addOne(1)) // 2
函式可帶有多個引數。
val add = (x: Int, y: Int) => x + y
println(add(1, 2)) // 3
或者不帶引數。
val getTheAnswer = () => 42
println(getTheAnswer()) // 42
2.4 方法
方法的表現和行為和函式非常類似,但是它們之間有一些關鍵的差別。 方法由def關鍵字定義。def後面跟著一個名字、引數列表、返回型別和方法體。
def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3
注意返回型別是怎麼在函式列表和一個冒號: Int之後宣告的。 方法可以接受多個引數列表。
def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
println(addThenMultiply(1, 2)(3)) // 9
或者沒有引數列表。
def name: String = System.getProperty("user.name")
println("Hello, " + name + "!")
還有一些其他的區別,但是現在你可以認為方法就是類似於函式的東西。 方法也可以有多行的表示式。
def getSquareString(input: Double): String = {
val square = input * input
square.toString
}
方法體的最後一個表示式就是方法的返回值。(Scala中也有一個return關鍵字,但是很少使用)
2.5 類
你可以使用class關鍵字定義一個類,後面跟著它的名字和構造引數。
class Greeter(prefix: String, suffix: String) {
def greet(name: String): Unit =
println(prefix + name + suffix)
}
greet方法的返回型別是Unit,表明沒有什麼有意義的需要返回。它有點像Java和C語言中的void。(不同點在於每個Scala表示式都必須有值,事實上有個Unit型別的單例值,寫作(),它不攜帶任何資訊) 你可以使用new關鍵字建立一個類的例項。
val greeter = new Greeter("Hello, ", "!")
greeter.greet("Scala developer") // Hello, Scala developer!
後面還會介紹類。
2.6 樣例類
Scala有一種特殊的類叫做樣例類(case class)。預設情況下,樣例類一般用於不可變物件,並且可作值比較。你可以使用case class關鍵字來定義樣例類。
case class Point(x: Int, y: Int)
你可以不用new關鍵字來例項化樣例類。
val point = Point(1, 2)
val anotherPoint = Point(1, 2)
val yetAnotherPoint = Point(2, 2)
並且它們的值可以進行比較。
if (point == anotherPoint) {
println(point + " and " + anotherPoint + " are the same.")
} else {
println(point + " and " + anotherPoint + " are different.")
} // Point(1,2) and Point(1,2) are the same.
if (point == yetAnotherPoint) {
println(point + " and " + yetAnotherPoint + " are the same.")
} else {
println(point + " and " + yetAnotherPoint + " are different.")
} // Point(1,2) and Point(2,2) are different.
關於樣例類,還有不少內容,後面介紹。
2.7 物件
物件是它們自己定義的單例項,你可以把它看作它自己的類的單例。 你可以使用object關鍵字定義物件。
object IdFactory {
private var counter = 0
def create(): Int = {
counter += 1
counter
}
}
你可以通過引用它的名字來訪問一個物件。
val newId: Int = IdFactory.create()
println(newId) // 1
val newerId: Int = IdFactory.create()
println(newerId) // 2
後面還會介紹它們。
2.8 特質
特質是包含某些欄位和方法的型別。可以組合多個特質。 你可以使用trait關鍵字定義特質。
trait Greeter {
def greet(name: String): Unit
}
特質也可以有預設的實現。
trait Greeter {
def greet(name: String): Unit =
println("Hello, " + name + "!")
}
你可以使用extends關鍵字來繼承特質,使用override關鍵字來覆蓋預設的實現。
class DefaultGreeter extends Greeter
class CustomizableGreeter(prefix: String, postfix: String) extends Greeter {
override def greet(name: String): Unit = {
println(prefix + name + postfix)
}
}
val greeter = new DefaultGreeter()
greeter.greet("Scala developer") // Hello, Scala developer!
val customGreeter = new CustomizableGreeter("How are you, ", "?")
customGreeter.greet("Scala developer") // How are you, Scala developer?
這裡,DefaultGreeter僅僅繼承了一個特質,它還可以繼承多個特質。 還會在後面介紹特質。
2.9 主方法
主方法是一個程式的入口點。JVM要求一個名為main的主方法,接受一個字串陣列的引數。 通過使用物件,你可以如下所示來定義一個主方法。
object Main {
def main(args: Array[String]): Unit =
println("Hello, Scala developer!")
}