所以我有這個宏:靜態返回類型宏
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:同意。 –