Scala函數

定義普通函數(=)(後面有不須要等號的)

參數類型必須聲明,函數返回類型無需聲明(只要不存在遞歸語句,scala會自動推導出返回值類型)
容許定義默認參數,有默認值的可不傳,跟Python一個德行,包括參數調用java

def helloWorld(name:String,age:Int=18) = {
    print(name,age)
}

helloWorld: (name: String, age: Int)Unit

//調用
helloWorld(age = 15)

遞歸函數

必須聲明返回類型,由於不知道你遞歸到何時編程

//斐波那契數列1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
//遞歸中的In = In-1 + In-2
9+8;8+7+7+6;7+6+6+5+6+5+5+4;6+5+5+4+5+4+4+3++4+3+3+2;5+4+4+3+4+3+3+2+3+2+2+1+2+1+1
 
def fab(n: Int): Int = {
  if (n < 1) {
    1
  }else{
    fab(n-1)+fab(n-2)
  }
}
print(fab(10))

變長參數

//接收到的參數爲**Seq[Int] = WrappedArray(1, 23, 4, 4, 1)**
 def sum(nums:Int*) = {
    var rst = 0
    for(num <- nums){//加強for循環
        rst += rst
    }
    rst
}

傳入一個已有序列

sum(1 to 5)         //錯誤,將一個Range賦值給Int
sum(1 to 5: _*)     //將1 to 5 這個Range解開爲單個傳入

與Python對比網絡

def sum(*nums):
    rst = 0
    for num in nums:
        rst += num
    retuen rst

與java對比app

int sum(int...  args){
    //todo...
}

神奇的執行邏輯(也許這就是函數式編程的冰山一角吧)

//當if...else...下方無語句時,從宏觀上看,if...else...做爲一個總體是** = **右邊**{塊表達式}**的最後一條語句,因此if...else...的返回值將做爲函數的返回值
def helloWorld(name: String, age: Int) = {
  if (age >= 18) {
    printf("Hello %s you are an adult!!\n", name)
    name
  } else {
    printf("Hello %s you are a little boy!!", name)
    name
  }
}
//以下
helloWorld: (name: String, age: Int)String

//反之,就不是最後一條語句了,若是沒有一個變量去接收if...else...表達式的值,if...else...的返回值就沒有一點意義了
def helloWorld(name: String, age: Int) = {
  if (age >= 18) {
    printf("Hello %s you are an adult!!\n", name)
    name    //多餘的表達式返回值
  } else {
    printf("Hello %s you are a little boy!!", name)
    name
  }
  val i = 1
  i
}
//以下
helloWorld: (name: String, age: Int)Int

過程(不須要返回值的函數)

沒有使用等號鏈接{}的函數稱爲過程,其返回值類型爲Unit,也就是沒有返回值函數式編程

//寫法1:不寫等號
def printName(name:String){
    print(name)
}
//寫法2:聲明無返回
def printName(name:String):Unit = {
    print(name)
}

lazy懶變量(用於耗時操做如網絡,文件IO)

變量後面的表達式在定義時候不會執行任何計算,直到第一次使用,在不少時候都須要,畢竟不是全部都須要一上來就加載的,或許你可能不會有機會使用呢函數

import scala.io.Source._
lazy val myfile = fromFile("D:\\123.txt").mkString      //myfile: String = <lazy>
print(myfile)                                           //這時候纔會執行計算

異常處理

使用了模式匹配的思想,catch字句裏的內容跟match裏的case是徹底同樣的。scala

//因爲異常捕捉是按次序,若是最廣泛的異常,Throwable,寫在最前面,則在它後面的case都捕捉不到,所以須要將它寫在最後面。
try{
  fromFile("D:\\asdasdasdasd").mkString
}catch{
  case e1:IOException => println("IO Exception")//e1是異常的名字,可使用 _ 代替
}finally {
  println("close resource")
}
相關文章
相關標籤/搜索