什么是Scala中的隐式证据?到底有什么好处呢?

时间:2014-02-17 01:13:57

标签: scala types implicit

我在许多SOF和博客文章中都看到了“隐含证据”一词,与类型信息的运行时保留有关。我在网上搜索但没有找到任何简单的解释是什么“隐含证据”。

这个概念出现了,例如,here

编辑:

评论特拉维斯的好答案:

来自Predef.scala

  sealed abstract class <:<[-From, +To] extends (From => To) 
      with Serializable

  private[this] final val singleton_<:< = 
      new <:<[Any,Any] { def apply(x: Any): Any = x }

  implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

我看不到unzip的“asPair”函数参数如何从singleton_<:<.asInstanceOf[A <:< A]派生。有人可以对此发表评论吗?

1 个答案:

答案 0 :(得分:11)

标准库中的一个很好的例子是unzip对例如List[A]的定义。 def unzip[A1, A2](implicit asPair: (A) ⇒ (A1, A2)): (List[A1], List[A2])

val (ks, vs) = List('a -> 1, 'b -> 2, 'c -> 3).unzip

目标是允许以下编译:

val (ks, vs) = List(1, 2, 3).unzip

但不是这样:

A

这是通过见证的隐式参数来完成的,列表的类型可以被视为一对。在上面的示例中,此证据由Predef.conforms提供,对于任何类型A <:< A,该证据将隐式提供A => A的实例,该实例是conforms的子类型。 def unzip[A1, A2](implicit asPair: A => (A1, A2)): (CC[A1], CC[A2]) = { val b1 = genericBuilder[A1] val b2 = genericBuilder[A2] for (xy <- sequential) { val (x, y) = asPair(xy) b1 += x b2 += y } (b1.result, b2.result) } 提供的实例当然只是身份功能。

如果您查看the definition of unzip,您会看到在这种情况下如何使用证据:

List[A]

即,它用于解构序列中的项目。请记住,此方法是在任何val (x, y) = xy上定义的,因此编写普通的旧unzip将无法编译。

隐式证据的其他应用可能有不同的目标(某些quite complex)并且可能以不同的方式使用隐式证据(它不一定只是一个函数),但基本模式通常会或多或少与您在{{1}}中看到的相同。