scala之旅-核心語言特性【多引數列表(currying)】(十二)
阿新 • • 發佈:2020-10-27
方法可以有多個形參列表
例子
這裡有個例子,在Scala集合Api中,特性Iterable 定義如下:
trait Iterable[A] { ... def foldLeft[B](z: B)(op: (B, A) => B): B ... }
foldLeft 將兩個引數的函式 op 應用於一個初始值z 上。然後所有集合的元素 ,從左到右。下面的列子是它的用法
起始值為0,foldLeft 這裡應用了函式 (m,n)=> m+n 來使列表中的每個元素與前一個值進行累加。
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res= numbers.foldLeft(0)((m, n) => m + n) println(res) // 55
使用案例
建議多個引數列表的使用案例包括:
驅動器型別判斷
碰巧在Scala中,型別推斷一次處理一個引數列表。你有如下的方法:
def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ???
然後你可以用如下的方式呼叫它,然後發現它不能通過編譯
def notPossible = foldLeft1(numbers, 0, _ + _)
你必須用下面的其中的一種方法進行呼叫:
def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _) def secondWay= foldLeft1(numbers, 0, (a: Int, b: Int) => a + b)
這是因為Scala不能同時推斷函式 _+_ 和 A、B。 通過將引數 op 移動至它自身的引數列表 ,第一個引數列表中的A和B的型別才能推斷出來。這個被推斷出來的型別就可以被應用與 _+_ 的型別推斷,最終推斷的結果為 (Int,Int) => Int
def foldLeft2[A, B](as: List[A], b0: B)(op: (B, A) => B) = ???
def possible = foldLeft2(numbers, 0)(_ + _)
這種定義方式就不需要額外的宣告,所有引數的型別都能推斷出來。
隱式引數
要將某些引數僅指定為隱式,必須將它們放到隱式引數列表中
舉例如下
def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ???
區域性應用
當一個方法被呼叫時缺少了一些數字或者引數列表,這時候便會產生一個以缺失形參列表作為實參的函式。這個被人稱為區域性應用的
舉例:
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]()) _ val squares = numberFunc((xs, x) => xs :+ x*x) println(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) val cubes = numberFunc((xs, x) => xs :+ x*x*x) println(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)
【注: 大概意思就是函式名也可以做變數。觸發函式時在這個變數後面加個括號】