Scala也是一種函數式編程語言,其函數也能當成值來使用。Scala提供了輕量級的語法用以定義匿名函數,支持高階函數,容許嵌套多層函數,並支持柯里化。Scala的case class及其內置的模式匹配至關於函數式編程語言中經常使用的代數類型。python
在Scala中,存在方法和函數兩個概念,方法和函數在語義上區別很細小。
Scala 中的方法跟 Java 的相似,方法是組成類的一部分。scala 中的函數則是一個完整的對象。
Scala中方法和函數在語法上區別不大,只是類中聲明的函數咱們叫方法,方法有重載和重寫,而函數則沒有。編程
[修飾符] def 函數名 ( 參數列表 ) [:返回值類型] = { 函數體 }
示例閉包
object Scala_Fun { def main(args: Array[String]): Unit = { test("hello") } /** * 普通函數示例 * @param str */ private def test(str:String):Unit = { println(str) } }
object Scala_Fun { def main(args: Array[String]): Unit = { // 無參,無返回值 def fun1(): Unit ={ println("無參且無返回值") } // 無參,有返回值 def fun2(): String ={ // 能夠省略return "張三" } // 有參,無返回值 def fun3(str:String): Unit ={ println(str) } // 有參,有返回值 def fun4(str:String): String ={ "hello:"+ str } // 關鍵字參數 } }
object Scala_Fun { def main(args: Array[String]): Unit = { // 可變參數 def fun1(names:String*): Unit ={ println(names) } fun1("張三","李四") // 可變參數不能放置在參數列表的前面,通常放在參數列表的最後 // 若是學過python,會發現傳參這裏跟python傳參很類似 /* 錯誤示範 def fun2(names:String*, count:Int): Unit ={ }*/ def fun2(count:Int,names:String*): Int ={ println(names) count } // 參數默認值 def fun3(name:String, age:Int = 18): Unit ={ println(name+ ":" + age) } // 命名傳參 fun3(name="張三") } }
object Scala_Fun { def main(args: Array[String]): Unit = { // Scala中函數能夠進行精簡,所謂是能省則省,固然前提是編譯器能夠自動推斷 def fun1(name:String): String ={ return "姓名:"+name } // 1.當函數有返回值時,能夠將函數體中最後一行執行的代碼做爲返回結果,因此能夠省略return關鍵字 def fun2(name:String): String ={ "fun2:"+name } println(fun2("張三")) // 2.若是編譯器能夠推斷出函數的返回值類型,返回值類型則能夠省略 def fun3(name:String)={ "fun3:"+name } println(fun3("張三")) // 3.若是函數體邏輯只有一行代碼,則函數體的大括號能夠省略 def fun4(name:String) = "fun4:"+name println(fun4("張三")) // 4.若是函數沒有參數,調用時候,小括號能夠省略 def fun5(): String ={ "fun5" } println(fun5) // 5.若是函數沒有提供參數,那聲明時,小括號能夠省略,調用時,也不能使用小括號 def fun6 = "fun6" println(fun6) // 6.若是函數使用Unit聲明沒有返回值,那函數體中的return關鍵字不會起做用。 /* def fun7():Unit={ return "張三" }*/ // 7.函數體中若是使用return關鍵字,則返回值不能省略 def fun8():String = { "fun8" } // 8.若是函數沒有返回值,Unit又不想用,那能夠同時省略等號,但保留花括號 def fun9(){ println("張三") } // 9.匿名函數:當只關心代碼邏輯,不關心函數名時,則函數名和def關鍵字能夠省略 // 匿名函數規則: (參數列表) => {函數邏輯} val fun10 = (name:String)=>println(name) fun10("張三") } }
1)數學概念編程語言
回顧下數學知識:
y=f(x) 這是最開始接觸的普通函數
y=g(f(x)) 這個就是咱們接觸到的高階函數在數學和計算機科學中,高階函數至少應當是知足下面一個條件的函數:
1)接受一個或者多個函數做爲參數
2)輸出一個函數函數式編程程序中咱們的高階函數也相似函數
2)柯里化Currying
柯里化:指的是將原來接受兩個參數的函數變成新的接收一個參數的函數,新的函數返回一個以原有第二個參數爲參數的函數
z = f(x, y)轉換成z=f(x)(y)scala
object Scala_Fun { def main(args: Array[String]): Unit = { def fun1():String = { "張三" } val v1 = fun1() // 調用函數,把函數的返回結果賦值給變量v1 val v2 = fun1 _ // 把函數做爲值賦值給變量v2 println(v1) println(v2) } }
object Scala_Fun { def main(args: Array[String]): Unit = { def fun1():String = { "張三" } def fun2(fun:()=>String): Unit ={ println(fun()) } fun2(fun1) } }
object Scala_Fun { def main(args: Array[String]): Unit = { def fun1():String = { "張三" } def fun2() = { fun1 _ } println(fun2()()) } }
函數在使用外部變量時,若是外部變量失效時,會將這個變量包含到當前的函數內部,造成閉合的效果,這個就是閉包。
匿名函數自己就是一種閉包。
代碼示例code
object Scala_Fun { def main(args: Array[String]): Unit = { def outFun(i:Int) ={ def inFun(j:Int) = { i + j } inFun _ } val res = outFun(10)(10) println(res) } }
惰性函數,也就是延遲加載,直到咱們首次對此取值,該函數纔會執行,使用lazy關鍵字聲明其返回值時,就會造成惰性函數。
示例:對象
object Scala_Fun { def main(args: Array[String]): Unit = { def fun():String = { println("張三") "張三" } lazy val res = fun() println(res) } }
object Scala_Fun { def main(args: Array[String]): Unit = { // 使用柯里化方式聲明函數 def fun1(a:Int,b:Int,f:(Int,Int)=>Int):Unit = { } def fun2(a:Int)(b:Int)(f:(Int,Int)=>Int) = { f(a,b) } // 調用函數 println(fun2(10)(20)(_ + _)) } }
學過Python的話,會發現這裏的高階函數和Python的高階函數大同小異。編譯器