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
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(三)筆記SQLOracle函式
- scala(三)函式函式
- now&sysdate函式差異函式
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(五)筆記SQLOracle函式
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(一)筆記SQLOracle函式
- Scala 的方法與函式函式
- 【譯】 React官方:函式元件與類元件的差異 ?React函式元件
- delphi中回撥函式差異函式
- 三角函式之積化和差公式函式公式
- scala語法 - 方法與函式函式
- 學習Scala 方法與函式函式
- scala函式函式
- 【Scala篇】--Scala中的函式函式
- Scala偏函式函式
- Scala本地函式函式
- Scala函式與函數語言程式設計函式函數程式設計
- resin與jetty解析el表示式差異Jetty
- [譯]React函式元件和類元件的差異React函式元件
- 三角函式之和差角公式函式公式
- 異常處理與異常函式函式
- scala 函式和方法函式
- Lambda表示式之爭:Scala vs Java 8Java
- 三角函式之和差化積公式函式公式
- Spark SQL scala和java版本的UDF函式使用SparkSQLJava函式
- scala 函式程式設計函式程式設計
- Scala的高階函式函式
- 【JAVA程式設計】實驗三 函式與物件Java程式設計函式物件
- 系統之間差異
- java字串“==”與“equals”的差異及與c#的區別Java字串C#
- ORACLE單行函式與多行函式之三:數值函式Oracle函式
- ORACLE函式介紹第三篇 著名函式之聚合函式Oracle函式
- Firefox與IE在CSS樣式表中的差異FirefoxCSS
- 建構函式與解構函式是否可以丟擲異常函式
- Java語言與C++語言的差異總結JavaC++
- IDP 與 DevOps平臺:相似之處與關鍵差異dev
- PostgreSQL與Oracle的sql差異SQLOracle