Макросы Scala, где они используются?
Я только что заметил, что у Scala есть макросы, но я никогда не видел кода, который их использует. Они также сильно отличаются от макросов препроцессора C и тому подобного. Чтение обзор макросов, не похоже, что они предлагают что-то, что ранее не было возможно в Scala. Под заголовком мотивации есть список вещей, которые макросы включают:
- виртуализация языка (перегрузка / переопределение семантики оригинальный язык программирования для обеспечения глубокого внедрения DSLs),
- овеществление программы (обеспечение программ средствами для проверки их собственный код),
- само-оптимизирование (само-применение домен-специфического оптимизации на основе овеществления программы),
- алгоритмические программы построение (генерация кода, который утомительно писать с помощью абстракции, поддерживаемые языком программирования).
далее в меню, есть экспериментальные макро-функции, такие как макросы типа, квазиквоты, нетипизированные макросы и даже больше. Очевидно, что на это есть спрос!
все это кажется хорошими функциями для людей, которые строят очень сложные библиотеки с сильным пониманием Scala. Но предлагают ли макросы что-то и для среднего разработчика Scala? Будет ли использование макросов делать мой код Scala лучше?
1 ответов
как "средний" разработчик Scala, вы, скорее всего, не будете писать макросы самостоятельно, если у вас нет очень веской причины.
макросы-это метод метапрограммирования времени компиляции, то есть вы программируете программы. Например, def-макрос, который является частью Scala 2.10, хотя и все еще "экспериментальный", выглядит как обычный метод, но всякий раз, когда вы вызываете этот метод в своем коде, компилятор заменит этот вызов тем, что этот макрос, скрытый за этим методом, будет производить (новый фрагмент кода.)
очень простой пример. Включить дату, когда ваш проект был скомпилирован в код:
import java.util.Date
import reflect.macros.Context
import language.experimental.macros
object CompileTime {
def apply(): Date = macro applyImpl
def applyImpl(c: Context)(): c.Expr[Date] = {
import c.universe._
val now = System.currentTimeMillis() // this is executed during compilation!
val nowExpr = c.Expr[Long](Literal(Constant(now)))
val code = reify(new Date(nowExpr.splice))
c.Expr(code.tree)
}
}
используя этот макрос (следующий код должен быть скомпилирован отдельно из кода макроса выше):
object MacroTest extends App {
println(s"This project was compiled on ${CompileTime()}")
}
(Если вы выполните это несколько раз, вы увидите, что время компиляции действительно постоянный)
короче говоря, макросы предлагают функциональность, которая была не доступный в любом предыдущая версия Scala. Вы можете делать с макросами то, что не можете сделать иначе (часто вы можете писать подобные вещи, используя отражение среды выполнения, но макросы проверяются во время компиляции).
как пользователь, вы будете все больше и больше подвергаться библиотекам, которые включают макросы, потому что они могут предоставлять мощные конструкции, которые полностью безопасны для типов. Например, автоматические сериализаторы для JSON из класса case могут быть реализованы с помощью макросов, поскольку макрос может проверять тип вашего класс case и построить правильную структуру программы (AST) для чтения и записи этого класса case, без опасности сбоя во время выполнения.
некоторые случайные ссылки