だから私はこのマクロ持っている:静的戻り値の型
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):私はどちらかc.Expr
上の型パラメータを削除する場合
scala> FooExample.foo
res0: Bar = [email protected]
scala> res0.launchMissiles
res1: String = launching
同じことが起こります。もし私が本当にfoo
と呼んでいる人が誰でも彼らがBar
を得ているのを見ることができないようにしたいのであれば、私は木の中に型格を追加しなければなりません。
これは実際にはかなり素敵です。たとえば、ある種のスキーマでマクロを指して、Vocabulary
クラスの匿名サブクラスを作成し、ボキャブラリの用語を表すメンバメソッドで作成できます。返されるオブジェクト
私は何をしているのか正確に理解したいと思いますので、いくつか質問があります。まず、foo
メソッドの戻り値の型は実際には何ですか? (オプションの)ドキュメンテーションのためだけに入手できますか?これは明らかに(例えば、私はこのケースでInt
にそれを変更することはできません)戻り値の型を制約し、私はそれを完全に削除する場合、私はこのようなエラーが出る:
scala> FooExample.foo
<console>:8: error: type mismatch;
found : Bar
required: Nothing
FooExample.foo
^
しかし、私ははにそれを変更することができますAny
と呼びますが、foo
を呼び出すと、静的型付きBar
が返されます。
第2に、この動作はどこかで指定されていますか?これはかなり基本的な問題のようですが、私は明確な説明や議論を検索することができませんでした。
@ som-snytt:しかし、私は 'foo'の戻り値の型が最終的な単語を持つことを期待していました。 –
'FooExample.foo'のリターン型アノテーションはここでは非常に奇妙です。これは、そうでなければ、マクロが動作することを期待する方法です。 – drstevens
@drstevens:合意しました。 –