溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

好程序員大數(shù)據(jù)學(xué)習(xí)路線分享高階函數(shù)

發(fā)布時間:2020-07-22 13:43:03 來源:網(wǎng)絡(luò) 閱讀:145 作者:wx5d42865f47214 欄目:大數(shù)據(jù)

  好程序員大數(shù)據(jù)學(xué)習(xí)路線分享高階函數(shù),我們通常將可以做為參數(shù)傳遞到方法中的表達(dá)式叫做函數(shù)

高階函數(shù)包含:作為值的函數(shù)、匿名函數(shù)、閉包、柯里化等等。

定義函數(shù)時格式:val 變量名 =?(輸入?yún)?shù)類型和個數(shù))?=>?函數(shù)實(shí)現(xiàn)和返回值類型和個數(shù)

“=”表示將函數(shù)賦給一個變量

“=>”左面表示輸入?yún)?shù)名稱、類型和個數(shù),右邊表示函數(shù)的實(shí)現(xiàn)和返回值類型和參數(shù)個數(shù)

作為值的函數(shù)

定義函數(shù)

scala> val func = (x:Int) => x * x
func: Int => Int = <function1>

scala> val func:Int => Int = x => x * x
func: Int => Int = <function1>

scala> func(3)
res0: Int = 9

函數(shù)調(diào)用

scala> val arr = Array(1,2,3,4)
arr: Array[Int] = Array(1, 2, 3, 4)

scala> val res = arr.map(x => func(x))
res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(func(_))
res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(func)
res: Array[Int] = Array(1, 4, 9, 16)

將方法轉(zhuǎn)化為函數(shù)

scala> def m1(x:Int):Int = x * x
m1: (x: Int)Int

scala> def m1(x:Int) = x * x
m1: (x: Int)Int

scala> def m2(x:Int) {x * x}
m2: (x: Int)Unit

scala> val f1 = m1 _
f1: Int => Int = <function1>

scala> val res = arr.map(x => m1(x))
res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(m1(_))
res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(m1)
res: Array[Int] = Array(1, 4, 9, 16)

匿名函數(shù)

在Scala中,你不需要給每一個函數(shù)命名,沒有將函數(shù)賦給變量的函數(shù)叫做匿名函數(shù)

scala> arr.map((x:Int) => x * x)
res3: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(x => x * x)
res4: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(m1)
res1: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(_ * 2)
res2: Array[Int] = Array(2, 4, 6, 8)

閉包

閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)

可以理解成,定義在一個函數(shù)內(nèi)部的函數(shù)

本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部鏈接起來的橋梁

object Bibao {

??def sum(f:Int => Int):(Int,Int) => Int = {
????def sumf(a:Int,b:Int):Int = {
??????if (a > b) 0 else f(a)+sumf(a + 1,b)
????}
????sumf ?//隱式轉(zhuǎn)換成函數(shù)
??}
??def main(args: Array[String]): Unit = {
????def sumInts = sum(x => x)
????println(sumInts(1,2))
??}
}

柯里化

柯里化指的是將原來接收兩個參數(shù)列表的方法或函數(shù)變成新的一個參數(shù)列表的方法或函數(shù)的過程

聲明和轉(zhuǎn)化

scala> def curry(x:Int)(y:Int) = x * y ?//聲明
curry: (x: Int)(y: Int)Int

scala> curry(3)(4)
res8: Int = 12

scala> val curry1 = curry(3) ?//轉(zhuǎn)換成方法 : 加""
curry1: Int => Int = <function1>

scala> curry1(5)
res9: Int = 15

scala> def curry2(x:Int) = (y:Int) => x * y ?//聲明
curry2: (x: Int)Int => Int

scala> val func = curry2(2) ?//直接轉(zhuǎn)化
func: Int => Int = <function1>

scala> func(4)
res16: Int = 8

scala> def curry3() = (x:Int) => x * x
curry3: ()Int => Int

scala> val func = curry3() ???//轉(zhuǎn)化空參
func: Int => Int = <function1>

scala> func(3)
res17: Int = 9

柯里化需要與隱式轉(zhuǎn)換相結(jié)合

implicit ?隱式的 -> 隱式值在當(dāng)前會話中同類型只能定義一次,不同類型可定義多個

scala> def m1(x:Int)(implicit y:Int=5) = x * y
m1: (x: Int)(implicit y: Int)Int

scala> m1(3)
res10: Int = 15

scala> m1(3)(6) ???//隱式值可以改變
res11: Int = 18

scala> implicit val x = 100 ?//定義成全局的隱式值,可以覆蓋
x: Int = 100

scala> m1(3)(6)
res12: Int = 18

scala> m1(3)
res13: Int = 300

scala> implicit val y = "abc"
y: String = abc

案例: 把數(shù)組中元祖的value相加

scala> val arr = Array(("xixi",1),("haha",2),("heihei",3))
arr: Array[(String, Int)] = Array((xixi,1), (haha,2), (heihei,3))

scala> ?arr.foldLeft(0)( + ._2) ?//(初始值)(上次計算結(jié)果+循環(huán)出的結(jié)果)
res15: Int = 6

Curry的Demo

object Context{ ??//一般情況會新建類,再在此地調(diào)用
??implicit val a = "yaoyao"
??implicit val b = 100
}
object Curry {

??//與變量沒有關(guān)系,系統(tǒng)自己匹配相同類型的值
??implicit val a = "yaoyao"
??implicit val b = 100

??def m1(str:String)(implicit name:String="xiaodan"){
????println(str + name)
??}

??def main(args: Array[String]): Unit = {
????import Context.a
????m1("Hello ")
??}
}

隱式轉(zhuǎn)換

作用: 隱式的對類的方法進(jìn)行增強(qiáng),豐富現(xiàn)有類庫的功能

隱式轉(zhuǎn)換:

繼承 -> 通過方法的重寫來對父類的方法增強(qiáng)

代理模式 -> 遠(yuǎn)程代理,多用于網(wǎng)站,代理一個實(shí)例,可以對實(shí)例方法增強(qiáng),在調(diào)用方法之前

????????代理,方法之后環(huán)繞

????裝飾模式 -> 裝飾模式也叫包裝模式,用java讀取文件時要用到IO流,也是對實(shí)例方法增強(qiáng) ?????????????????????????

????new BufferInputStream(new FileInputStream).read()

就是用到了裝飾模式和門面模式 ->

裝飾模式是顯示的包裝,隱式轉(zhuǎn)換就是隱式的做了包裝

門面模式起到了隱式包裝的作用

隱式轉(zhuǎn)換函數(shù) : 是指以implicit關(guān)鍵字聲明的帶有單個參數(shù)的函數(shù)

案例: 用隱式轉(zhuǎn)換,實(shí)現(xiàn)從給定的URI直接能調(diào)用read方法讀取文件內(nèi)容

object MyPredef {

??//implicit def fileToRichFile(file:String) = new RichFile(file)

??implicit val fileToRichFile = (file:String) =>new RichFile(file)

}

object RichFile {

??def main(args: Array[String]): Unit = {

????val file = "e://wordcount.txt"

// ???//顯示的實(shí)現(xiàn)了對file的方法增強(qiáng)

// ???val richFile = new RichFile(file)

// ???val content: String = richFile.read()

// ???println(content)

????//隱式轉(zhuǎn)換

????import MyPredef.fileToRichFile

????val content = file.read()

????println(content)

??}

}

class RichFile(val file:String){

??//創(chuàng)建read方法

??def read():String = {

????Source.fromFile(file).mkString

??}

}

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI