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

jhe*_*dus 5 types scala implicit

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

例如,这里提出了这个概念.

编辑:

评论特拉维斯的好答案:

来自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]
Run Code Online (Sandbox Code Playgroud)

我没有看到如何从unzip's" asPair"函数参数派生出来singleton_<:<.asInstanceOf[A <:< A].有人可以对此发表评论吗?

Tra*_*own 11

标准库中的一个很好的例子是unzip例如:a 的定义List[A]:

def unzip[A1, A2](implicit asPair: (A) ? (A1, A2)): (List[A1], List[A2])
Run Code Online (Sandbox Code Playgroud)

目标是允许以下编译:

val (ks, vs) = List('a -> 1, 'b -> 2, 'c -> 3).unzip
Run Code Online (Sandbox Code Playgroud)

但不是这个:

val (ks, vs) = List(1, 2, 3).unzip
Run Code Online (Sandbox Code Playgroud)

这是通过,一个隐式自变量来实现证人,该列表的类型可以被视为一对.在上面的例子中,这个证据是由提供的Predef.conforms,对于任何类型A都会隐式地提供一个实例A <:< A,它是一个子类型A => A.由conformswill 提供的实例当然只是身份功能.

如果你看一下定义unzip,你会看到在这种情况下如何使用证据:

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)
  }
Run Code Online (Sandbox Code Playgroud)

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

隐式证据的其他应用可能有不同的目标(一些非常复杂),并且可能以不同的方式使用隐式证据(它不一定只是一个函数),但基本模式通常或多或少与您看到的相同与unzip.