簡單型別

型別類只是一個帶有一個或多個型別引數的 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