【问题标题】:Implicit class in ScalaScala中的隐式类
【发布时间】:2015-01-16 19:04:23
【问题描述】:

我有以下一段代码。我必须确认它是否是如何工作的。任何人都可以提供解释

object Implicits
{
  implicit class RichSeq[A](val xs:Seq[A])
  {
    def mapD[B](function:A => B):Seq[B] = xs.map(function)
  }
}

这有点像我可以与序列一起使用的映射抽象。 因此,如果我导入这个 Implicits.RichSeq,我可以在任何 Seq[A] 上使用这些方法,因为这会将 Seq[A] 转换为 RichSeq[A]。

import Implicits.RichSeq._
val xs:Seq[Int] = Seq(22,33)
val output:Seq[Int] = xs.mapD(_+22)

我想知道这是如何工作的,因为当我在 Seq[A] 类型上使用 mapD 时,它会搜索从 Seq[A] 到 RichSeq[A] 的隐式转换。它在哪里找到这个隐式转换,因为这是隐式类?

它是否将隐式类扩展为:

隐式 def RichSeq[A](val xs:Seq[A]) = new RichSeq(xs)

我认为它可能在里面做这些事情。ne1 知道吗?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    隐式类只是一个简写

    class Foo(a: A)
    implicit def pimpMyA(a: A) = new Foo(a)
    

    如果类的构造函数只采用一个非隐式参数,则可以将类注释为 implicit

    这是相关文档,您可以在其中阅读更多信息:http://docs.scala-lang.org/overviews/core/implicit-classes.html


    在您的具体示例中,这意味着任何Seq[A] 都可以隐式提升为RichSeq[A]

    编译器会找到隐含的,因为你导入了它,所以它在作用域中可用。

    你可以看到这段代码的实际java输出

    val x = Seq(1, 2, 3)
    x.mapD(_ + 22)
    

    通过使用带有选项-Xprint:typer 的scala REPL。这是输出的相关位

    $line3.$read.$iw.$iw.Implicits.RichSeq[Int]($line3.$read.$iw.$iw.x).mapD[Int](((x$1: Int) => x$1.+(22)));
    

    经过一些打磨后相当于

    Implicits.RichSeq(x).mapD(x$1 => x$1 + 22)
    

    附带说明,您只需导入Implicits._。具体的隐式解析规则可以参考Where does Scala look for implicits?

    【讨论】:

    • 完全正确..这就是它的工作方式。通过分析这段代码的java转换,它的工作方式非常清楚..感谢您的描述
    【解决方案2】:

    你只需要导入

    import Implicits._
    

    它将隐式注入到你的作用域中。

    我可以确认 Scala 正在使用您当前的 Seq 创建一个新的 RichSeq。 如果您想尝试类似的行为,请编写类似的内容:

    object Implicits {
      implicit class RichSeq[A](val xs:Seq[A]) {
        println("fuu") // print "fuu" when RichSeq is created 
        def mapD[B](function:A => B):Seq[B] = xs.map(function)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多