だから私はこのマクロを持っています:
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
を返したいと 3 回言いました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
静的に型付けされたものを取得できます。Bar
foo
第二に、この動作はどこかで指定されていますか? これはかなり基本的な一連の問題のように思えますが、明確な説明や議論を検索することはできませんでした。