Макросы Scala: строковый литерал, назначенный переменной, не совпадает

Я использую макроаннотацию из библиотеки Scio Spotify. Я хотел бы определить переменную String введите и аннотируйте, как это:

val schemaString = """schema here"""
@BigQueryType.fromSchema(outputString) class BigQuery

Это не компилируется, однако, если я аннотирую String напрямую работает:

@BigQueryType.fromSchema("""schema here""") class BigQuery

Глядя на код, это соответствие выполняется здесь, по сути, код выглядит следующим образом:

def str(tree: c.Tree) = tree match {
      // "string literal"
      case Literal(Constant(s: String)) => s
      // "string literal".stripMargin
      case Select(Literal(Constant(s: String)), TermName("stripMargin")) => s.stripMargin
      case _ => c.abort(c.enclosingPosition, errorMessage)
    }

Вопрос в том, почему это не соответствует переменной, но соответствует ли строка? А есть ли способ заставить первый пример работать?

1 ответ

Решение

Проблема в том, что значение строковых переменных может быть недоступно во время компиляции, когда выполняются макросы. Что если бы это было:

val schemaString = doSomeComplexFunction()
@BigQueryType.fromSchema(schemaString) class BigQuery

Теоретически, возможно, макрос мог бы искать, где определен val, и позволить ему работать, если ему просто присвоено буквальное значение, но даже это может стать сложным, если вы начнете думать о области действия.

Так что нет, вероятно, нет способа заставить первый пример работать.

Другие вопросы по тегам