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)
时间: 2024-09-14 19:23:22

Coursera Scala 5-3:Implicit的相关文章

Coursera Scala 5-5 List:Reduction of Lists

Coursera Scala 5-5 List:Reduction of Lists 另一个list常用的操作是:连结集合元素.例如sum(list) ReduceLeft 使用ReduceLeft可以很方便的编写通用的连结方法 def sum(xs: List[Int]) = (0 :: xs) reduceLeft ((x,y) => x+y) def product(xs : List[Int]) = (1 :: xs) reduceLeft((x,y) => x*y) FoldLeft

Coursera Scala 2-5,6:类

Coursera Scala 2-5,6:类 class Rational(n: Int, d: Int) { require(d != 0) private val g = gcd(n.abs, d.abs) //将构造器传入的参数,赋值成成员变量,外部才可以访问 val numer = n / g val denom = d / g def this(n: Int) = this(n, 1) def +(that: Rational): Rational = new Rational( nu

Coursera Scala 5-2:Pairs和Tuple

Coursera Scala 5-2:Pairs和Tuple pair: (x,y) scala> val (label,value) = (1,"s") label: Int = 1 value: String = s scala> (1,"s") res0: (Int, String) = (1,s) 超过两个元素的就是tuple了 (T1,....,Tn)是Scala.Tuplen[T1,...,Tn]的缩写 (e1,....,en)是Scala.

Coursera Scala 5-4:List的高阶函数

Coursera Scala 5-4:List的高阶函数 Recurring Patterns for Computations on Lists 重复出现的Lists计算模式 lists的很多函数有相似的结构,重复出现的模式有: 用某个方法转换每个元素 用某个条件提取元素 用某种方法链接元素 函数式编程语言,让程序员能写出更通用的计算模式,通过使用高阶函数. Applying a Function to Elements of a List 将一个list的所有元素,进行转换.例子:返回一个新

Coursera Scala 4-1:函数作为对象

Coursera Scala 4-1:函数作为对象 Functions Types Relate to Classes Scala是纯粹的面向对象的语言,函数是拥有apply方法的对象. 函数类型A=>B等价于: package scala trait Function1[A,B]{ def apply(x:A):B } Functions Values Ralate to Objects 匿名函数 (x:Int) => x*x 等价于: { class AnonFun extends Fun

Coursera Scala 4-7:Lists

Coursera Scala 4-7:Lists Lists val nums = List(1,3,4) val empty = List() val fruit = List("apples","oranges") val diag3 = List(List(1,0,0),List(0,1,0),List(0,0,1)) immutable List是递归的,arrays则不是 The List Type 和arrays一样,lists的元素必须是相同类型的.

Coursera Scala 4-6:模型匹配

Coursera Scala 4-6:模型匹配 匹配值 val times = 1 times match { case 1 => "one" case 2 => "two" case _ => "some other number" } List(('a',1), ('b',2), ('a',1)) match { case Nil => println("null") case (C, n) ::

Coursera Scala 4-3:子类型和泛型

Coursera Scala 4-3:子类型和泛型 Type Bounds def assertAllPos[S <: IntSet](r: S): S = ... S <: T 表示S是T的子类 S >: T表示S是T的父类 也可以这么用: [S >: NonEmpty <: IntSet] 协变covariant 这个的意思是: 如果List是convariant的,S<:T (S是T的子类)成立,那么List[S]<:List[T]也成立 covariant

Coursera Scala 2-1:高阶函数

把函数当做参数,传递给函数(好绕-..-),称为高阶函数. 高阶函数使我们的代码保持DRY(Dont't Repeat Yourself) 举个例子 一个返回所有扩展名为".scala"的文件的方法: def filesHere = (new java.io.File(".")).listFiles def filesEnding(query: String) = for (file <- filesHere; if file.getName.endsWith