1

メソッドは、多くの場合、明らかなパラメーター名で宣言されます。

def myMethod(s: String, image: BufferedImage, mesh: Mesh) { ... }

パラメータ名はパラメータの型に対応しています。

1) "s" は String によく使用されます

2) Int の場合は「i」

3) クラスという名前の 1 つの単語の小文字のクラス名 (メッシュ -> メッシュ)

4) 長いクラス名のクラス名の最後の単語を小文字化 (BufferedImage -> image)

(もちろん、すべてのメソッドと引数にとって便利というわけではありません。もちろん、誰かが他のルールを好むでしょう…)

Scala マクロは、コードでいくつかの式を生成することを目的としています。次のような正しい Scala 式に変換する特定のマクロをいくつか書きたいと思います。

// "arguments interpolation" style
// like string interpolation
def myMethod s[String, BufferedImage, Mesh] 
{ /* code using vars "s", "image", "mesh" */ }

// or even better:
mydef myMethod[String, BufferedImage, Mesh] 
{ /* code using vars "s", "image", "mesh" */ }

出来ますか?

4

2 に答える 2

2

「なぜ」(いいえ、なぜそれをしたいのですか?) は別として、私の知る限り、マクロは (現在の状態では) メソッドや型を生成できず、式のみを生成できるため、答えはいいえです。

于 2013-01-30T14:20:33.590 に答える
2

現在、それは不可能であり、おそらく不可能です。マクロは独自の構文を導入できません。マクロは有効な Scala コード (コンパイル時に実行可能) で表現する必要があり、有効な Scala コードを生成する必要があります (有効な Scala AST と呼ぶのが適切です)。

表示されている例は両方とも有効な Scala コードではないため、マクロはそれらを処理できません。それにもかかわらず、マクロ パラダイスの現在のナイトリー ビルドには、型指定されていないマクロが含まれています。展開後に型チェックされる Scala コードを書くことができます。つまり、次のように書くことができます。

forM({i = 0; i < 10; i += 1}) {
  println(i)
}

最初のパラメーター リスト内の中括弧が必要であることに注意してください。これは、コードを記述するときに型チェックは行われませんが、有効な Scala AST を表す必要があるためです。

このマクロの実装は次のようになります。

def forM(header: _)(body: _) = macro __forM

def __forM(c: Context)(header: c.Tree)(body: c.Tree): c.Tree = {
  import c.universe._
  header match {
    case Block(
      List(
        Assign(Ident(TermName(name)), Literal(Constant(start))),
        Apply(Select(Ident(TermName(name2)), TermName(comparison)), List(Literal(Constant(end))))
      ),
      Apply(Select(Ident(TermName(name3)), TermName(incrementation)), List(Literal(Constant(inc))))
    ) =>

    // here one can generate the behavior of the loop
    // but omit full implementation for clarity now ...

  }
}

既に型チェックされた式の代わりに、マクロは展開後に型チェックされるツリーのみを期待します。メソッド呼び出し自体は 2 つのパラメーター リストを予期します。これらのパラメーターの型は、アンダースコアが使用されている場合、展開フェーズの後に遅延する可能性があります。

現在、利用可能なドキュメントが少しありますが、非常にベータ版であるため、多くのことが将来変更される可能性があります。

型マクロを使用すると、次のように書くことができます。

object O extends M {
  // traverse the body of O to find what you want
}

type M(x: _) = macro __M

def __M(c: Context)(x: c.Tree): c.Tree = {
  // omit full implementation for clarity ...
}

これは、物事を冷やすことができるため、ボディ全体の型チェックを遅らせるのに便利です...


Scalas 構文を変更できるマクロは、現時点では計画されておらず、おそらく良い考えではありません。それらがいつの日か起こるかどうかはわかりません。これを教えてくれるのは未来だけです。

于 2013-01-30T16:32:19.440 に答える