Şu anda makrolarıyla biraz etrafına oynuyorum ve belki bu burada kötü bir fikir zaten, ama bir param atamak benim sorunum:Scala makro yapıbozuma fonksiyonu
Aşağıdaki makro:
def using[A <: { def close(): Unit }, B](resource: A)(f: A => B) = macro usingImpl[A, B]
def usingImpl[A <: { def close(): Unit }, B](c: Context)(resource: c.Expr[A])(f: c.Expr[A => B]): c.Expr[B] = {
import c.universe._
f.tree match {
case Function(params, body) =>
//val ValDef(modifiers, name, tpt, _) = params.head
c.Expr[B](
Block(
List(
//ValDef(modifiers, name, tpt, resource.tree)
ValDef(params.head.symbol, resource.tree)
),
body
)
)
case _: Select =>
reify {
val res = resource.splice
try {
f.splice(res)
} finally {
res.close()
}
}
}
}
Select
durumunda, sadece işlevi çağırıp kaynağı kapatırım, iyi çalışıyor. Ancak, Function
durumunda, param değerini kaynağa atamak ve bedeni aramak istiyorum. ValDef
'un kullanımdan kaldırılan oluşturucusunu kullandığımda, bu, Symbol
ve Tree
alır, her şey yolunda çalışır. Out-commented 4-args yaratıcısı kullanıyorum, x$1
değerinin kapsamda olmadığını belirten bir derleyici hatası alıyorum. Her iki sürüm ürettiğini kod baktığımızda, tam olarak aynı görünüyor:
Expr[Int]({
<synthetic> val x$1: Test.Foo = new Test.this.Foo();
x$1.bar.+(23)
})
belki bir yolu var mı, basitçe params.head
kullanmak ve bir değer atamak için? Herhangi bir yardım için teşekkürler!
düzenlemek:, dışarı-yorumladı sürümünü kullanıyorsam Dediğim gibi
object Test extends App {
import Macros._
class Foo {
def close() {}
def bar = 3
}
println(using(new Foo)(_.bar + 3))
}
, bana bir derleyici hata veriyor baskılar olun:
böyle makro arama AST ve sonunda şu ileti: [error] symbol value x$1 does not exist in Test$delayedInit$body.apply
Ve 2.10.1 kullanıyorum.
'params.head' işlevinin bozulmaması gayet iyi çalışmalıdır — Hatanızı (2.10.0 veya 2.10.1 ile) yeniden oluşturamıyorum ve aslında uncommented sürümüyle bir derleyici hatası elde edemiyorum. Makroyu aramak için kullandığınız kodu gönderir misiniz? –
benim sorum – drexin
Scala içine yıkıcılar yapmaya çalışıyorsunuz? İyi fikir! –