美文网首页
转载 bounds

转载 bounds

作者: fengjixcuhui | 来源:发表于2017-04-13 16:03 被阅读0次

    上界

    case class Pair[T <: Comparable[T]](first: T, second: T) { def smaller = if (first.compareTo(second) < 0) first else second } Pair("1", "2").smaller // OK, String is subtype of Comparable[String] Pair(1, 2).smaller // Compile Error, Int is not subtype of Comparable[Int]

    隐式参数

    import scala.math.Ordering case class Pair[T](first: T, second: T){ def smaller(implicit order: Ordering[T]) = order.min(first, second) }

    当T为Int时

    Pair(1, 2).smaller

    编译器实际调用

    Pair(1, 2).smaller(Ordering.Int)
    其中Ordering.Int定义在Ordering的伴生对象中
    object Ordering { trait IntOrdering extends Ordering[Int] { def compare(x: Int, y: Int) = if (x < y) -1 else if (x == y) 0 else 1 } implicit object Int extends IntOrdering }

    当T为自定义类型

    import scala.math.Ordering case class Point(x: Int, y: Int) object Point { implicit object point extends Ordering[Point] { def compare(lhs: Point, rhs: Point): Int = (lhs.x + lhs.y) - (rhs.x + rhs.y) } }
    Pair(Point(0, 0), Point(1, 1)).smaller
    等价于
    Pair(Point(0, 0), Point(1, 1)).smaller(Point.point)

    case class Pair[T](first:T,second:T){ def smaller(implicit ord : Ordering[T]) = ord.min(first,second) } case class Student(val id:Int,val name:String) object Student { implicit object StudentOrdering extends Ordering[Student] { override def compare(x: Student, y: Student): Int = x.id - y.id } } object ContextBound { def main(args: Array[String]): Unit = { val smaller = Pair(Student(1,"zhangsan"), Student(2,"lisi")).smaller println(smaller) } }

    上下文界定

    implicitly实用函数

    import scala.math.Ordering case class Pair[T : Ordering](first: T, second: T) { def smaller = implicitly[Ordering[T]].min(first, second) }
    其中,implicitly定义在Predef中,用于从「冥界」中提取T的隐式值。
    def implicitly[T](implicit e: T) = e

    更好、更漂亮

    import scala.math.Ordering case class Pair[T : Ordering](first: T, second: T) { def smaller = Ordering[T].min(first, second) }
    其中,Ordering[T]首先调用了object Ordering的apply方法,从而便捷地找到了Order[T]的隐式值.
    object Ordering { def apply[T](implicit ord: Ordering[T]) = ord }
    所以Ordering[T].min等价于implicitly[Ordering[T]].min

    视图限定

    如果使用Ordered,及其「隐式参数」的机制,smaller可以实现为:
    import scala.math.Ordered case class Pair[T](first: T, second: T) { def smaller(implicit order: T => Ordered[T]) = { if (first < second) first else second } }
    implicit order: T => Ordered[T]在smaller的局部作用域内,即是一个「隐式参数」,又是一个「隐式转换函数」,从而设计可以简化为:
    import scala.math.Ordered case class Pair[T](first: T, second: T) { def smaller(implicit order: T => Ordered[T]) = { if (first < second) first else second } }
    又因为在Predef预定义了从IntRichInt的隐式转换,而RichIntOrdered[Int]的子类型;所以在Predef定义的implicit Int => RichInt的隐式转换函数可作为隐式参数implicit order: T => Ordered[T]的隐式值。
    Pair(1, 2).smaller
    等价于
    Pair(1, 2).smaller(Predef.intWrapper _)
    上述简化的设计,使得隐式参数order没有必要存在,而且这样的「实现模式」较为常见,可归一为一般模式:视图界定
    import scala.math.Ordered case class Pair[T <% Ordered[T]](first: T, second: T) { def smaller = if (first < second) first else second }
    注意:T <% Ordered[T]表示:T可以隐式转换为Ordered[T];而T <: Ordered[T]表示:TOrdered[T]的一个子类型。

    相关文章

      网友评论

          本文标题:转载 bounds

          本文链接:https://www.haomeiwen.com/subject/mrmbattx.html