【发布时间】:2012-11-20 03:14:35
【问题描述】:
所以我有这个宏:
import language.experimental.macros
import scala.reflect.macros.Context
class Foo
class Bar extends Foo { def launchMissiles = "launching" }
object FooExample {
def foo: Foo = macro foo_impl
def foo_impl(c: Context): c.Expr[Foo] =
c.Expr[Foo](c.universe.reify(new Bar).tree)
}
我已经说过三遍我希望foo 返回一个Foo,但我可以执行以下操作(在 2.10.0-RC3 中):
scala> FooExample.foo
res0: Bar = Bar@4118f8dd
scala> res0.launchMissiles
res1: String = launching
如果我删除 c.Expr 上的类型参数,也会发生同样的事情。如果我真的想确保打电话给foo 的人看不到他们得到的是Bar,我必须在树本身中添加一个类型说明。
这实际上非常棒——例如,这意味着我可以将宏指向某种模式,并创建一些 Vocabulary 类的匿名子类,其成员方法表示词汇表中的术语,这些将可用在返回的对象上。
不过,我想确切地了解我在做什么,所以我有几个问题。首先,foo 方法的返回类型实际上是什么?它仅可用于(可选)文档吗?它清楚地限制了返回类型(例如,在这种情况下,我不能将其更改为 Int),如果我完全删除它,我会收到如下错误:
scala> FooExample.foo
<console>:8: error: type mismatch;
found : Bar
required: Nothing
FooExample.foo
^
但是我可以将其更改为Any,当我调用foo 时仍然会得到一个静态类型的Bar。
其次,这种行为是否在某处指定?这似乎是一组相当基本的问题,但我无法搜索到明确的解释或讨论。
【问题讨论】:
-
@som-snytt:但我仍然希望
foo上的返回类型拥有最终决定权(尽管我也很高兴它没有)。 -
FooExample.foo上的返回类型注释在这里非常奇怪。这就是我期望宏的行为方式。 -
@som-snytt 你能详细说明一下吗?宏应该能够与谁通信?
标签: scala types macros scala-2.10 scala-macros