Макросы 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, и позволить ему работать, если ему просто присвоено буквальное значение, но даже это может стать сложным, если вы начнете думать о области действия.
Так что нет, вероятно, нет способа заставить первый пример работать.