Scala與Java差異(三)之函式
一、函式定義
(1)函式的定義與呼叫
在Scala中定義函式時,需要定義函式的函式名、引數、函式體。
第一個函式如下所示:
def sayHello(name: String, age: Int) = {
if (age > 18) { printf("hi %s, you are a big boy\n", name); age }
else { printf("hi %s, you are a little boy\n", name); age
}
sayHello("leo", 30)
Scala要求必須給出所有引數的型別,但是不一定給出函式返回值的型別,只要右側的函式體中不包含遞迴的語句,Scala就可以自己根據右側的表示式推斷出返回型別。
(2)在程式碼塊中定義包含多行語句的函式體
單行的函式:def sayHello(name: String) = print("Hello, " + name)
如果函式體中有多行程式碼,則可以使用程式碼塊的方式包裹多行程式碼,程式碼塊中最後一行的返回值就是整個函式的返回值。與Java中不同,不是使用return返回值的。
比如如下的函式,實現累加的功能:
def sum(n: Int) = {
var sum = 0;
for(i <- 1 to n) sum += i
sum
}
(3)遞迴函式與返回型別
如果在函式體內遞迴呼叫函式自身,則必須手動給出函式的返回型別。
例如,實現經典的斐波那契數列:
9 + 8; 8 + 7 + 7 + 6; 7 + 6 + 6 + 5 + 6 + 5 + 5 + 4; ....
def fab(n: Int): Int = {
if(n <= 1) 1
else fab(n - 1) + fab(n - 2)
}
二、函式的預設引數和帶名引數
(1) 預設引數
在Scala中,有時我們呼叫某些函式時,不希望給出引數的具體值,而希望使用引數自身預設的值,此時就定義在定義函式時使用預設引數。
def sayHello(firstName: String, middleName: String = "William", lastName: String = "Croft") = firstName + " " + middleName + " " + lastName
如果給出的引數不夠,則會從作往右依次應用引數。
(2)Java與Scala實現預設引數的區別
Java:
public void sayHello(String name, int age) {
if(name == null) {
name = "defaultName"
}
if(age == 0) {
age = 18
}
}
sayHello(null, 0)
Scala:
def sayHello(name: String, age: Int = 20) {
print("Hello, " + name + ", your age is " + age)
}
sayHello("leo")
(3)帶名引數
在呼叫函式時,也可以不按照函式定義的引數順序來傳遞引數,而是使用帶名引數的方式來傳遞。
sayHello(firstName = "Mick", lastName = "Nina", middleName = "Jack")
還可以混合使用未命名引數和帶名引數,但是未命名引數必須排在帶名引數前面。
sayHello("Mick", lastName = "Nina", middleName = "Jack")
三、函式的變長引數
(1)變長引數
在Scala中,有時我們需要將函式定義為引數個數可變的形式,則此時可以使用變長引數定義函式。
def sum(nums: Int*) = {
var res = 0
for (num <- nums) res += num
res
}
sum(1, 2, 3, 4, 5)
(2)使用序列呼叫變長引數
在如果想要將一個已有的序列直接呼叫變長引數函式,是不對的。比如val s = sum(1 to 5)。此時需要使用Scala特殊的語法將引數定義為序列,讓Scala直譯器能夠識別。這種語法非常有用!一定要好好注意,在spark的原始碼中大量地使用到了。
val s = sum(1 to 5: _*)
案例:使用遞迴函式實現累加
def sum2(nums: Int*): Int = {
if (nums.length == 0) 0
else nums.head + sum2(nums.tail: _*)
四、函式的過程、lazy值和異常
(1)過程
在Scala中,定義函式時,如果函式體直接包裹在了花括號裡面,而沒有使用=連線,則函式的返回值型別就是Unit。這樣的函式就被稱之為過程。過程通常用於不需要返回值的函式。
過程還有一種寫法,就是將函式的返回值型別定義為Unit。
def sayHello(name: String) = "Hello, " + name
def sayHello(name: String) { print("Hello, " + name); "Hello, " + name }
def sayHello(name: String): Unit = "Hello, " + name
(2)lazy值
在Scala中,提供了lazy值的特性,也就是說,如果將一個變數宣告為lazy,則只有在第一次使用該變數時,變數對應的表示式才會發生計算。這種特性對於特別耗時的計算操作特別有用,比如開啟檔案進行IO,進行網路IO等。
import scala.io.Source._
lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
即使檔案不存在,也不會報錯,只有第一個使用變數時會報錯,證明了表示式計算的lazy特性。
val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
def lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
(3) 異常
在Scala中,異常處理和捕獲機制與Java是非常相似的。
try {
throw new IllegalArgumentException("x should not be negative")
} catch {
case _: IllegalArgumentException => println("Illegal Argument!")
} finally {
print("release resources!")
}
try {
throw new IOException("user defined exception")
} catch {
case e1: IllegalArgumentException => println("illegal argument")
case e2: IOException => println("io exception")
}
相關文章
- Scala與Java差異(五)之Map與TupleJava
- Scala與Java差異(二)之條件控制與迴圈Java
- scala(三)函式函式
- Scala 的方法與函式函式
- 【譯】 React官方:函式元件與類元件的差異 ?React函式元件
- scala語法 - 方法與函式函式
- 學習Scala 方法與函式函式
- 三角函式之積化和差公式函式公式
- [譯]React函式元件和類元件的差異React函式元件
- 三角函式之和差角公式函式公式
- python:dis包中dis()和Bytecode()函式的差異Python函式
- 三角函式之和差化積公式函式公式
- 【JAVA程式設計】實驗三 函式與物件Java程式設計函式物件
- IDP 與 DevOps平臺:相似之處與關鍵差異dev
- java字串“==”與“equals”的差異及與c#的區別Java字串C#
- 思科1500與3600差異
- 大資料Scala系列之樣例類_Option_偏函式大資料函式
- OpenFaaS實戰之三:Java函式Java函式
- Scala與Java的關係Java
- Scala(一):函式、流程控制、引數函式
- Golang 基礎之函式使用 (三)Golang函式
- PostgreSQL與Oracle的sql差異SQLOracle
- 【譯】框架與庫的差異框架
- Java8之Stream-函式式介面Java函式
- java8 新特性之函式式介面Java函式
- 非同步操作系列之Generator函式與Async函式非同步函式
- 關於scala中的主建構函式函式
- Django基礎三之檢視函式Django函式
- Python 與 JavaScript 語法差異點PythonJavaScript
- 反向代理與正向代理差異分析
- Java8新特性探索之函式式介面Java函式
- 三、函式函式
- Java版本功能差異一覽指南 - marcobehlerJava
- matlab符號函式的求導與差分的計算Matlab符號函式求導
- 從 Java 到 Scala (三): object 的應用JavaObject
- Bootstrap和Tailwind CSS之間的差異?bootAICSS
- Dart語法篇之集合操作符函式與原始碼分析(三)Dart函式原始碼
- 【探索蔚藍奧秘】海與洋的差異及海洋色彩與味道之謎