Scala中的隐式证据是什么?到底有什么好处呢? [英] What is implicit evidence in Scala? What is it good for?

查看:55
本文介绍了Scala中的隐式证据是什么?到底有什么好处呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I see the term "implicit evidence" in many SOF and blog posts, related to runtime retention of type information. I searched the net but have not found any simple explanation what "implicit evidence" is.

例如,在此处出现.

对特拉维斯的好答案的评论:

A comment to Travis' nice answer:

来自 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]

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

I don't see how the unzip's "asPair" function parameter can be derived from singleton_<:<.asInstanceOf[A <:< A]. Could someone please comment on this?

推荐答案

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

A good example in the standard library is the definition of unzip on e.g. a List[A]:

def unzip[A1, A2](implicit asPair: (A) ⇒ (A1, A2)): (List[A1], List[A2])

目标是允许编译以下内容:

The goal is to allow the following to compile:

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

但不是这样:

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

这是通过一个隐式参数实现的,该隐式参数表示可以将列表的类型视为一对.在上面的示例中,此证据由 Predef.conforms 提供,该证据对于任何类型的A,将隐式提供A <:< A的实例,该实例是A => A的子类型. conforms提供的实例当然只是身份函数.

This is accomplished via an implicit argument that witnesses that the type of the list can be viewed as a pair. In the example above this evidence is provided by Predef.conforms, which for any type A will implicitly provide an instance of A <:< A, which is a subtype of A => A. The instance provided by conforms will of course just be the identity function.

如果您查看的定义unzip ,您将看到在这种情况下如何使用证据:

If you look at the definition of unzip, you'll see how the evidence is used in this case:

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)
  }

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

I.e., it's used to deconstruct the items in the sequence. Remember that this method is defined on any List[A], so writing plain old val (x, y) = xy wouldn't compile.

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

Other applications of implicit evidence may have different goals (some quite complex) and may use the implicit evidence in different ways (it's not necessarily just a function), but the basic pattern is generally going to be more or less the same as what you see with unzip.

这篇关于Scala中的隐式证据是什么?到底有什么好处呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆