Coursera Scala 5-3:Implicit
Coursera Scala 5-3:Implicit
歸並排序
上一節課的排序函數不夠通用,類型隻適用Int:
object mergesort{
def msort(xs: List[Int]):List[Int] = {
val n = xs.length/2
if(n==0) xs
else{
def merge(xs:List[Int],ys: List[Int]):List[Int] = (xs,ys)match {
case (Nil,ys) => ys
case (xs,Nil) => xs
case (x::xs1,y::ys1) =>
if(x<y) x::merge(xs1,ys1)
else y::merge(xs,ys1)
}
val (fst,snd) = xs splitAt n
merge(msort(fst),msort(snd))
}
}
val nums = List(2,-4,5,7,1)
msort(nums)
}
更通用的歸並排序寫法
object mergesort{
def msort[T](xs: List[T])(lt:(T,T) => Boolean):List[T] = {
val n = xs.length/2
if(n==0) xs
else{
def merge(xs:List[T],ys: List[T]):List[T] = (xs,ys)match {
case (Nil,ys) => ys
case (xs,Nil) => xs
case (x::xs1,y::ys1) =>
if(lt(x,y)) x::merge(xs1,ys1)
else y::merge(xs,ys1)
}
val (fst,snd) = xs splitAt n
merge(msort(fst)(lt),msort(snd)(lt))
}
}
val nums = List(2,-4,5,7,1)
msort(nums)((x:Int,y:Int) => x < y)
val fruits = List("apple","pineapple","orange")
msort(fruits)((x: String,y:String) =>x.compareTo(y)<0)
}
Implicit隱式轉換
在函數的參數中使用 編譯器會根據類型得到正確的隱含參數
對排序函數再改造一下,scala提供了常用的比較操作Ordering,在scala.math包下:
object mergesort{
def msort[T](xs: List[T])(ord:Ordering)):List[T] = {
val n = xs.length/2
if(n==0) xs
else{
def merge(xs:List[T],ys: List[T]):List[T] = (xs,ys)match {
case (Nil,ys) => ys
case (xs,Nil) => xs
case (x::xs1,y::ys1) =>
if(ord.lt(x,y)) x::merge(xs1,ys1)
else y::merge(xs,ys1)
}
val (fst,snd) = xs splitAt n
merge(msort(fst)(ord),msort(snd)(ord))
}
}
val nums = List(2,-4,5,7,1)
msort(nums)(Ordering.Int)
val fruits = List("apple","pineapple","orange")
msort(fruits)(Ordering.String)
}
利用implicit,我們可以省去一些參數。scala編譯器會幫我們匹配類型:
def msort[T](xs: List[T])(implicit ord:Ordering)):List[T] = {
...
}
調用時隻需:
msort(List(1,2,3)) 或者msort(List("1","2","3"))
隱式轉換條件
編譯器如何查找implicit定義:
- is marked implicit
- has a type compatible with T
- is visible at the point of the function call, or is de?ned in a
companion object associated with T.
以上的原則 Ordering是包含類型參數的 完整的形式是 Ordering[T]
所以編譯器在使用 List(1,2,3) 時會正確找到 Ordering[Int]
而為 List("1","2","3") 時則為Ordering[String]
如:
def less[T](a:T,b:T)(implicit ord:math.Ordering[T]):Boolean=ord.lt(a, b)
less(1,2)
最後更新:2017-04-03 05:39:11