简单类型

类型类只是一个带有一个或多个类型参数的 trait

trait Show[A] {
  def show(a: A): String
}

不是扩展类型类,而是为每个受支持的类型提供类型类的隐式实例。将这些实现放在类型类的伴随对象中允许隐式解析在没有任何特殊导入的情况下工作:

object Show {
  implicit val intShow: Show[Int] = new Show {
    def show(x: Int): String = x.toString
  }

  implicit val dateShow: Show[java.util.Date] = new Show {
    def show(x: java.util.Date): String = x.getTime.toString
  }

  // ..etc
}

如果要保证传递给函数的泛型参数具有类型类的实例,请使用隐式参数:

def log[A](a: A)(implicit showInstance: Show[A]): Unit = {
  println(showInstance.show(a))
}

你还可以使用上下文绑定

def log[A: Show](a: A): Unit = {
  println(implicitly[Show[A]].show(a))
}

像任何其他方法一样调用上面的 log 方法。如果找不到传递给 logA 的隐式 Show[A] 实现,它将无法编译

log(10) // prints: "10"
log(new java.util.Date(1469491668401L) // prints: "1469491668401"
log(List(1,2,3)) // fails to compile with
                 // could not find implicit value for evidence parameter of type Show[List[Int]]

此示例实现了 Show 类型类。这是一个常见的类型类,用于将任意类型的任意实例转换为 Strings。即使每个对象都有 toString 方法,但是并不总是清楚 toString 是否以有用的方式定义。使用 Show 类型,你可以保证传递给 log 的任何内容都有明确定义的转换为 String