2016-10-26 12 views
1

К сожалению, наиболее интуитивный способ,Scala - значение вставки в quasiquote

val world = "Earth" 
val tree = q"""println("Hello $world")""" 

приводит

Error:(16, 36) Don't know how to unquote here 
val tree = q"""println("Hello $world")""" 
        ^

потому $ в quasiquotes ожидает tree.

val world = "Earth" 
val tree = q"""println(${c.literal(s"Hello $world")})""" 

работает, но очень некрасиво и я получаю Intellij предупреждение о том, что c.literal является устаревшим, и я должен использовать quasiquotes, вместо этого.

Итак ... как мне это сделать?

UPDATE

В ответ на комментарий Флавиан в:

import scala.language.experimental.macros 
import scala.reflect.macros._ 

object TestMacros { 

    def doTest() = macro impl 

    def impl(c: blackbox.Context)(): c.Expr[Unit] = { 
    import c.universe._ //access to AST classes 
    /* 
    val world = "Earth" 
    val tree = q"""println(${c.literal(s"Hello $world")})""" 
    */ 

    val world = TermName("Earth") 
    val tree = q"""println("Hello $world")""" 

    tree match { 
     case q"""println("Hello Earth")""" => println("succeeded") 
     case _ => c.abort(c.enclosingPosition, s"huh? was: $tree") 
    } 

    c.Expr(tree) //wrap tree and tag with its type 
    } 
} 

дает

Error:(18, 40) Don't know how to unquote here 
    val tree = q"""println("Hello $world")""" 
           ^

ответ

5

Вам нужен TermName или что-нибудь компилятор примитивно.

Настоящая проблема заключается в том, что вы смешиваете интерполяторы, не осознавая. Интерполятор в мире привет - это действительно строковый интерполятор, а не квазикватот, который хорош на неквалифицированных деревьях, как вы предлагаете.

Это один из способов это сделать:

import c.universe._ 

val world = TermName("Earth") 
val tree = q"""println("Hello" + ${world.decodedName.toString})""" 
+0

могли бы вы подробнее остановиться на «интерпол в мире привет действительно строка Интерполятор, не quasiquote один»? – User1291

+0

также, ни один из двух способов, по которым вы предлагаете работу. во-первых, компилятор будет жаловаться, что «мир» ему не известен, во-вторых, он будет жаловаться, что он не знает, как его недооценивать. – User1291

+0

Я уже тестировал, прежде чем отвечать, ты что-то делаешь, а Ли ошибается. Какую версию scala вы используете? – flavian