跳轉到內容

Scala/函式

來自華夏公益教科書,開放的書籍,為開放的世界

函式基礎

[編輯 | 編輯原始碼]

Scala 中的函式定義非常靈活,並且仍然簡潔。讓我們看一個簡單的函式定義

def simpleFunction = 3
println(simpleFunction) //Prints "3".

在上面,"def" 關鍵字用於開始函式定義。在 "def" 關鍵字之後,緊跟著函式的名稱,在本例中為 "simpleFunction"。 "=" 用於表示函式具有返回值。在 "=" 之後是一些表示式,表示函式體,在本例中為 3。然後我們透過簡單地寫出函式的名稱來呼叫該函式,並打印出結果。請注意,由於函式沒有引數,我們沒有使用 "()" 來呼叫它。

由於範圍是表示式,並且範圍中的最後一條語句是範圍的返回值,我們可以編寫一個更高階的函式,如下所示

def someFunction = {
  val a = 42 - 13*2
  a*a
}
println(someFunction) //Prints "256".

最後的語句 "a*a" 是一個表示式,因此成為範圍的返回值,並且由於範圍是函式的表示式,它成為函式的返回值。如果範圍中的最後一條語句是非表示式語句,則返回型別將為 "Unit",表示沒有返回值,如下所示

def printNameFunction = println("Jack Sparrow")
printNameFunction //Prints "Jack Sparrow".

由於函式沒有返回值,但只有副作用,因此在函式定義中表示這一點是一種良好的風格。除了使用 "=" 來表示函式體之外,還可以只使用一個範圍

def printNameFunction2 {println("Captain Haddock")}
printNameFunction2 //Prints "Captain Haddock".

無論最後一個表示式的值是什麼,一個放棄 "=" 的函式總是會有 "Unit" 作為返回型別。

上面的函式都有些無聊,因為它們不接受任何引數。函式透過在名稱後附加一個 "()" 來給出引數列表,如下所示

def cubed(a:Int) = a*a*a
def pythagoras(a:Double, b:Double) = math.sqrt(a*a + b*b)
println(cubed(-3)) //Prints "-27".
println(pythagoras(3, 4)) //Prints "5.0".

函式中的每個引數都用 "," 分隔,呼叫函式需要使用 "()" 並按正確的順序將引數放在括號中。請注意,引數的型別註釋是必須的。

你可能已經注意到,在上面,返回值從未明確宣告。原因是 Scala 編譯器通常可以推斷出正確的返回值型別。如果你出於某種原因想要顯式宣告它,可以在最後一個引數列表和主體開始(用 "=" 或 "{" 表示)之間進行宣告,如下所示

def squared(a:Int):Int = a*a

需要明確宣告結果型別(截至 Scala 2.9.1)的一個常見情況是遞迴函式,即呼叫自身的函式。最基本的例子是階乘函式

def factorial(n:Int):Int = {
  if (n == 0) 1
  else n*factorial(n-1)
}
//ERROR: Does not compile!
/*def factorial(n:Int) = {
  if (n == 0) 1
  else n*factorial(n-1)
}*/

函式名稱

[編輯 | 編輯原始碼]

待辦事項:關於函式名稱的語法。

字首函式

[編輯 | 編輯原始碼]

待辦事項:關於字首函式和中綴函式的語法。

函式優先順序

[編輯 | 編輯原始碼]

待辦事項:關於函式優先順序以及 ":" 的語法。

函式型別

[編輯 | 編輯原始碼]

待辦事項:函式型別,例如 "Int => Double" 或 "(String => String) => String"。

華夏公益教科書