所以我有这个宏:静态返回类型宏
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 = [email protected]
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'上的返回类型注释在这里非常奇怪。否则,我会期待宏的行为。 – drstevens
@drstevens:同意。 –