2009-11-30 36 views
4

当试图确定一个库的工作方式时,隐式转换是令人困惑的。例如,查看像'val foo:Foo = 1'这样的表达式,将1转换为Foo?scala:追踪implicits选择和其他代码魔法

是否有可能指示阶库(或REPL)打印出被同时计算表达式执行代码路径?

回答

7

您可以添加“-Xprint:打字员”的编译器命令行(或“-Ybrowse:打字员”的Swing GUI的浏览器)来查看代码与显式应用的转换。

+0

你所说的Swing GUI的浏览器意思? – 2011-12-04 16:35:22

+0

Swing = java客户端GUI小部件。 GUI =图形用户界面。 “Swing GUI Browser”=丑陋的对话框,里面有可扩展的树形控件。 (1)关于 – 2011-12-20 21:11:44

3

作为替代打印出的转换,人们必须意识到implicits不能刚出来的蓝色。你必须以某种方式将它们纳入范围。替代方案是:

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

请注意,对象scala.Predef默认情况下都会导入到作用域中,这是Scala默认含义进入作用域的方式。

+0

。实际上,这个问题源于这样一个事实,即使用scalacheck你可以导入org.scalacheck._,然后你可以做一些事情,比如“val vowel:Gen [Char] ='A'|'E'|'I'|' O'|'U'|'Y'“,这显然使用隐式转换。事实证明,其中一个scalacheck文件具有“导入Gen. {value,...}”(值是执行转换的隐式方法) – IttayD 2009-11-30 17:03:57

+0

我怀疑import是否是相关的。在这种情况下,我会查看Gen的对象伴侣。 – 2009-12-01 10:54:32

+0

是的,来自同伴对象,但我不需要执行'import org.scalacheck.Gen._'来获取它,因此隐式导入隐式完成(双关意图) – IttayD 2009-12-01 11:17:46

0

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