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!")
}
Другие вопросы по тегам