【问题标题】:scala: tracing implicits selection and other code magicsscala:跟踪隐式选择和其他代码魔术
【发布时间】:2010-12-21 13:12:11
【问题描述】:

当试图弄清楚库是如何工作的时,隐式转换令人困惑。例如,查看像 'val foo: Foo = 1' 这样的表达式,是什么将 1 转换为 Foo?

是否可以指示 scala 库(或 REPL)在计算表达式时打印出正在执行的代码路径?

【问题讨论】:

    标签: scala read-eval-print-loop


    【解决方案1】:

    您可以将“-Xprint:typer”添加到编译器命令行(或“-Ybrowse:typer”用于swing GUI 浏览器)以查看显式应用转换的代码。

    【讨论】:

    • swing GUI 浏览器是什么意思?
    • Swing = java 客户端 GUI 小部件。 GUI = 图形用户界面。 “Swing GUI 浏览器”= 丑陋的对话框,其中包含可扩展的树控件。
    【解决方案2】:

    作为打印转换的替代方法,必须意识到隐式不能突然出现。您必须以某种方式将它们纳入范围。替代方案是:

    1. 显式import 语句。当y 是一个对象时,请注意import x.y._,因为这是将隐式引入范围的唯一方法。
    2. 正在转换为其他对象的类的对象伴侣。
    3. 目标类的对象伴侣,只要该目标以某种方式明确(例如在您的示例中)。

    注意 scala.Predef 对象默认全部导入作用域,这是 Scala 的默认隐式进入作用域的方式。

    【讨论】:

    • 关于 (1)。实际上,这个问题源于这样一个事实,即使用 scalacheck 'import org.scalacheck._' 然后你可以做类似 "val vowel: Gen[Char] = 'A' | 'E' | 'I' | ' O' | 'U' | 'Y'",显然使用了隐式转换。事实证明,其中一个 scalacheck 文件具有“import Gen.{value,...}”(value 是执行转换的隐式方法)
    • 我怀疑导入是相关的。在这种情况下,我会在 Gen 的对象伴侣内部寻找一个隐含的。
    • 是的,来自伴随对象,但我不需要执行 'import org.scalacheck.Gen._' 来获取它,因此隐式导入是隐式完成的(双关语)跨度>
    【解决方案3】:

    scalac -print 在应用隐式类型转换后打印代码。

    class A{
        val x : String = "hi" drop 1 
    }
    

    将导致:

    package <empty> {
      class A extends java.lang.Object with ScalaObject {
        @remote def $tag(): Int = scala.ScalaObject$class.$tag(A.this);
        private[this] val x: java.lang.String = _;
        <stable> <accessor> def x(): java.lang.String = A.this.x;
        def this(): A = {
          A.super.this();
          A.this.x = scala.this.Predef.forceRandomAccessCharSeq(
            scala.this.Predef.stringWrapper("hi").drop(1));
          ()
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 2014-11-05
      相关资源
      最近更新 更多