美文网首页
Essential Scala: Bounds

Essential Scala: Bounds

作者: 刘光聪 | 来源:发表于2016-07-05 20:40 被阅读216次

上界

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]

隐式参数

可以提供「隐式参数」,改善smaller的设计。

import scala.math.Ordering

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

TInt

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)

上下文界定

import scala.math.Ordering

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

上例通过显式地提供「隐式参数」,当此手法成为一种实现模式时,Scala很自然地引入了「上下文界定」。

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 = implicitly[Ordering[T]].min(first, second)
}

可以进一步简化为:

import scala.math.Ordering

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

其中,Ordering[T]首先调用了object Orderingapply方法,从而便捷地找到了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 (order(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]的一个子类型。

相关文章

  • Essential Scala: Bounds

    上界 隐式参数 可以提供「隐式参数」,改善smaller的设计。 当T为Int 编译器实际调用: 其中Orderi...

  • Essential Scala: Literals

    Scala对象系统 总体上,Scala对象系统可分为两类: 引用类型 值类型 引用类型 AnyRef的子类 使用n...

  • essential scala: 伴生对象

    essential scala: 伴生对象 有时候我们想创建属于类的方法,在java中使用static关键字. 在...

  • Essential Scala: Import Specfica

    Scala是一门很自由的程序设计语言,程序员可以根据具体场景,选择最合适的武器来解决所面对的问题。例如,相对于Ja...

  • Essential Scala: DRY List

    在函数式设计中,递归是一种重要的思维。本文通过List的实现为例,阐述Scala在设计具有「不变性」数据结构的思路...

  • Essential Scala: Ice Breaker

    Scala是一门结合OO, FP特性的混血儿,支持多种范式的程序设计语言。本文通过一个简单的例子,开启Scala的...

  • Essential Scala:Parameter Type &

    参数化类型 Reader 定义泛型的Reader[+T],并赋予协变的能力。 StringReader FileR...

  • Essential Scala: Loan Pattern

    资源自动回收是计算机工程实践中一项重要的实现模式,例如: C++: RAII技术 Java7以后:try-with...

  • Essential Scala: Type Constraint

    Scala提供了3个类型约束的类: T =:= U: T是否等于U T <:< U: T是否为U的子类型 T <%...

  • 详解 Scala 中的 Context Bounds

    What is Context Bounds? 这是Scala 2.8 引入的新特性,通常与类型类模式(type ...

网友评论

      本文标题:Essential Scala: Bounds

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