Scala: код запускается только при отладке (эквивалент #ifdef?)
В C++ я могу написать:
#ifdef DEBUG
cout << "Debugging!" << endl;
Есть ли какой-нибудь эквивалент в Scala?
3 ответа
Обычная идиома @elidable.
Scaladoc покрывает ваш обычный вариант использования:
http://www.scala-lang.org/api/current/scala/annotation/elidable.html
Эквивалентная форма препроцессора C#ifdef - это макрос Scala:
package app.macros.log
import scala.language.experimental.macros
import reflect.macros.Context
object SimpleMacroLogger {
private val on = true
def info(msg: String): Unit = macro info_impl
def info_impl(c: Context)(msg: c.Expr[String]): c.Expr[Unit] = {
import c.universe._
if (on) {
reify {
println(msg.splice)
}
} else {
reify {
// Nothing
}
}
}
}
использоваться с
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}
Код гораздо сложнее, но его использование лучше: нет необходимости в окружении #ifdef/#endif и т. Д. Так что это не загромождает ваш код.
Если установлено значение false, макрос полностью удаляет запись в журнал.
Все, что находится внутри reify, войдет в результирующий байт-код, другой код запускается во время компиляции. Это особенно относится к if (on)....
Если вы хотите, чтобы код выполнялся только при соблюдении определенных условий, вы можете использовать стандартный блок if:
if (SystemProperties.get("debug.mode").exists(_ == "true") {
println("Debugging!")
}
Если вы по какой-либо причине обеспокоены тем, что оператор даже не должен появляться в скомпилированном выводе, тогда вы можете использовать блок if с константным выражением времени компиляции. В этих случаях javac / scalac будет правильно делать вывод, что условие никогда не будет истинным, и поэтому даже не включает байт-код для блока. (Очевидно, вам нужно изменить свою сборку, чтобы получить постоянное значение "true" для отладочных сборок и "false" для сборок prod.)
object Constants {
final val DEBUG = false
}
// ...
if (Constants.DEBUG) {
println("Debugging!")
}