Scala 官網:http://www.scala-lang.org/
一、高階函數
1、函數化簡2、常見的高階函數package com.example.scala /** * Created by Bruce on 2017/6/12. */ /** * ⑴接收其他函數作為參數的函數,被稱作高階函數(higher-order function); * ⑵Scala中,由于函數是一等公民,是以可以直接将某個函數傳入其他函數,作為參數; * ⑶高階函數的另外一個功能是将函數作為傳回值; * ⑷高階函數可以自動推斷出函數類型,而不需要寫明類型;而且對于隻有一個參數的函數,還可以省去其小括号; * 如果僅有的一個參數在右側的函數體内隻使用一次,則還可以将接收參數省略,用_來替代即可; * Array(2,3,5,6).map((x:Int)=>{x*3}) * Array(2,3,5,6).map((x)=>{x*3}) * Array(2,3,5,6).map((x)=>x*3) * Array(2,3,5,6).map(x=>x*3) * Array(2,3,5,6).map(_*3) */ object functionN extends App{ def myTest(x: Int, y: Int) = { x * y + 20 } def fun1(f: (Int, Int) => Int, a: Int, b: Int) = { f(a, b) } println(fun1(myTest, 100, 5)) }
二、隐式轉換
1、隐式轉換
⑴Scala提供的隐式轉換和隐式參數功能,是非常有特色的功能,是Java等程式設計語言所沒有的功能。它可以允許手動指定将某種類型的對象轉換成其他類型的對象。
⑵Scala的隐式轉換,其實最核心的就是定義隐式轉換函數,即implicit conversion function。定義的隐式轉換函數,隻要在編寫的程式内引入,就會被Scala自動使用。Scala會根據隐式轉換函數的簽名,在程式中使用到隐式轉換函數接收的參數類型定義的對象時,會自動将其傳入隐式轉換函數,轉換為另外一種類型的對象并傳回。這就是隐式轉換。
⑶隐式轉換函數叫什麼名字是無所謂的,通常不會由使用者手動調用,而是由Scala進行調用。然而,如果要手動使用隐式轉換,則需要對隐式轉換函數進行導入。是以通常将隐式轉換函數的名稱命名為“one2one”的形式。
⑷要實作隐式轉換,隻要在程式可見的範圍内定義隐式轉換函數即可。Scala會自動使用隐式轉換函數。隐式轉換函數與普通函數唯一的文法差別就是,要以implicit開頭,而且要指定函數傳回類型。
package com.example.scala /** * Created by Bruce on 2017/6/12. */ class SpecialPerson(val name: String) class Student1(val name: String) class Older(val name: String) object Implicit extends App{ var ticketNm = 0 def buySpecialTticket(spe: SpecialPerson) = { ticketNm += 1 spe.name + "'s ticket number is " + ticketNm } implicit def object2SpecialPerson(obj: Object):SpecialPerson = { //隐式轉換函數需要使用implict聲明 //隐式轉換的函數名稱習慣為:被轉換類型2目标類型 //隐式轉換函數需要顯性的定義傳回類型 println("************************") if (obj.getClass == classOf[Student1]) { val stu = obj.asInstanceOf[Student1] new SpecialPerson(stu.name) } else if (obj.getClass == classOf[Older]) { val old = obj.asInstanceOf[Older] new SpecialPerson(old.name) } else new SpecialPerson("None") } println(buySpecialTticket(new Student1("bruce"))) }
2、隐式轉換-加強類
⑴隐式轉換強大之處就是可以在不知不覺中加強現有類型的功能。也就是說,可以為某個類定義一個加強版的類,并定義互相之間的隐式轉換,進而讓源類在使用加強版的方法時,由Scala自動進行隐式轉換調用。
3、隐式轉換作用域與發生時機package com.example.scala /** * Created by Bruce on 2017/6/12. */ /** * 隐式轉換強大之處就是可以在不知不覺中加強現有類型的功能。 * 也就是說,可以為某個類定義一個加強版的類,并定義互相之間的隐式轉換, * 進而讓源類在使用加強版的方法時,由Scala自動進行隐式轉換為加強類,然後在調用該方法; * @param name */ class Man(val name: String) class SuperMan(val name: String) { def emitLaser() = println("emiting laser......................") } object SuperMan extends App { val bruce=new Man("bruce") implicit def man2superman(man:Man):SuperMan={ new SuperMan(man.name) } bruce.emitLaser() }
package com.example.scala /** * Created by Bruce on 2017/6/12. */ /** * ⑴Scala預設會使用兩種隐式轉換: * 一種是源類型,或者目标類型的伴生對象内的隐式轉換函數; * 一種是目前程式作用域内的可以用唯一辨別符表示的隐式轉換函數; * ⑵如果隐式轉換函數不在上述兩種情況下的話,那麼就需要手動使用import文法引入某個包下的隐式轉換函數, * 通常情況下,僅僅在需要進行隐式轉換的地方,比如某個函數或者方法内,用import導入隐式轉換函數, * 這樣可以縮小隐式轉換函數的作用域,避免不必要的隐式轉換; * ⑶發生時機 * ①調用某個函數,但是給函數傳入的參數的類型,與函數定義的接收參數類型不比對; * ②使用某個類型的對象,調用某個方法,而這個方法并不存在于該類型時; * ③使用某個類型的對象,調用某個方法,雖然該類型有這個方法,但是給方法傳入的參數類型,與方法定義的接收參數的烈性不比對; * @param name */ class Man2(val name: String) object SuperMan2{ implicit def man22superman2(man:Man):SuperMan2={ new SuperMan2(man.name) } } class SuperMan2(val name: String) { def emitLaser() = println("emiting laser......................") } object Implicit extends App { import com.example.scala.SuperMan2.man22superman2 val bruce=new Man("bruce") bruce.emitLaser() }
4、隐式參數
⑴所謂的隐式參數,指的是在函數或者方法中,定義一個用implicit修飾的參數,此時Scala會嘗試找到一個指定類型的,用implicit修飾的對象,即隐式值,并注入參數。
⑵Scala會在兩個範圍内查找:一種是目前作用域内可見的val或者var定義的隐式變量;一種是隐式參數類型的伴生對象内的隐式值。
package com.example.scala /** * Created by Bruce on 2017/6/12. */ /** * ⑴所謂的隐式參數,指的是在函數或者方法中,定義一個用implicit修飾的參數,此時Scala會嘗試找到一個指定類型的,用implicit修飾的對象,即隐式值,并注入參數。 * ⑵Scala會在兩個範圍内查找:一種是目前作用域内可見的val或者var定義的隐式變量;一種是隐式參數類型的伴生對象内的隐式值。 */ object implicitParse extends App{ def test(implicit value:String) =println("the value is "+value) test("Scala") implicit val name="bruce" test }