为什么Scala reify无法按照文档显示? [英] Why does Scala reify not work as according to the docs?

查看:85
本文介绍了为什么Scala reify无法按照文档显示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用于2.10.3的Scala API文档说,我可以使用refiy生成代表给定Scala表达式的抽象语法树。因此,我可以这样做:

  scala> val uni = scala.reflect.runtime.universe 
uni:scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse@4e42766

scala> uni reify {1 to 3}
res2:uni.Expr [scala.collection.immutable.Range.Inclusive] = Expr [scala.collection.immutable.Range.Inclusive](Predef.intWrapper(1).to( 3))

在上面的示例中,我得到了所需的内容: Predef.intWrapper(1).to(3))(方便地扩展了要执行的操作)。



当我尝试验证 1 + 3 的大小,但是,我没有执行我想要执行的操作。

  scala> uni reify {1 + 3} 
res5:uni.Expr [Int(4)] = Expr [Int(4)](4)

这是预期的行为吗? + 是原始操作,因此没有被整形吗?



Scala文档显示了一个整形示例,它暗示

  reify {2 + 4} // Apply(Select(Literal(Constant(2 )),newTermName( $ plus)),List(Literal(Constant(4)))))

如何检查 1 + 3 的正确扩展表示形式(如果存在),以及如何检索任何表达式的详细表示形式(在上面)?



编辑:现在,我看到Scala文档中的表示形式显示是由 showRaw 生成的。但是,我仍然无法为上面的示例重现 2 + 4 的原始表示形式。

解决方案

请参见这个答案,作者:Eugene Burmako:


将宏连接到类型检查(在某种意义上,宏参数
在宏扩展之前进行了类型检查),并且类型检查会折叠
常量


reify 是使用宏实现的。



您应该防止像这样不断折叠:

  {
val i = 1
showRaw {reify {i + 2} .tree}
}
// Apply(Select(Ident(newTermName( i)),newTermName( $ plus)),List(Literal(Constant(2))))


The Scala API docs for 2.10.3 say that I can, "Use refiy to produce the abstract syntax tree representing a given Scala expression." Accordingly, I can do:

scala> val uni = scala.reflect.runtime.universe 
uni: scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse@4e42766

scala> uni reify { 1 to 3 } 
res2: uni.Expr[scala.collection.immutable.Range.Inclusive] = Expr[scala.collection.immutable.Range.Inclusive](Predef.intWrapper(1).to(3))

In the example above, I get what I am looking for: Predef.intWrapper(1).to(3)) (a handy expanded representation of the operations to be performed).

When I attempt to reify 1 + 3, however, I do not the representation of the operations to perform that I desire.

scala> uni reify { 1 + 3 }
res5: uni.Expr[Int(4)] = Expr[Int(4)](4)

Is this expected behavior? Is + a primitive operation and, hence, not reified?

The Scala docs show an example of reification that implies that an even more useful representation is available:

reify{ 2 + 4 } // Apply( Select( Literal(Constant(2)), newTermName("$plus")), List( Literal(Constant(4)) ) )

How can I examine the proper expanded representation for 1 + 3 (if one exists) and how can I retrieve a detailed representation of any expression (immediately above)?

Edit: I see now that the representation show in the Scala docs is generated by showRaw. However, I still cannot reproduce the raw representation show in the example above for 2 + 4.

解决方案

See this answer by Eugene Burmako:

macros are wired into typechecking (in the sense that macro arguments are typechecked prior to macro expansion), and typechecking folds constants

reify is implemented using macro.

You should just prevent constant folding like this:

{
  val i = 1
  showRaw{ reify{i + 2}.tree }
}
// Apply(Select(Ident(newTermName("i")), newTermName("$plus")), List(Literal(Constant(2))))

这篇关于为什么Scala reify无法按照文档显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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