【问题标题】:Scala: Code only run when debugging(#ifdef equivalent?)Scala:代码仅在调试时运行(#ifdef 等效?)
【发布时间】:2013-05-29 16:42:58
【问题描述】:

我可以用 C++ 编写:

#ifdef DEBUG
cout << "Debugging!" << endl;

Scala 中是否有任何等价物?

【问题讨论】:

  • 顺便说一句,JVM 和它的 JIT 通常在消除死代码方面做得很好,因此很可能简单的 final val DEBUG = falsedef log(str: String) = if (DEBUG) print(str) 在大多数情况下就足够了。

标签: debugging scala compiler-directives scala-macros


【解决方案1】:

传统的成语是@elidable。

scaladoc 涵盖了您的常规用例:

http://www.scala-lang.org/api/current/scala/annotation/elidable.html

【讨论】:

  • 除了在 Predef.assert 中间接使用之外,可能没有人使用 elidable,但实际上从未删除任何东西。如评论中所述,if (DEBUG) 标志为 final val(仅限推断类型)或 val DEBUG: true = true 保证简单消除。
【解决方案2】:

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 等。所以它不会弄乱你的代码。

如果您将 on 设置为 false,宏将完全删除日志记录。

reify 中的任何内容都将进入生成的字节码, 其他代码在编译时运行。这尤其适用于 if (on) ...

【讨论】:

    【解决方案3】:

    如果您希望代码仅在某些条件成立时执行,您可以使用标准 if 块:

    if (SystemProperties.get("debug.mode").exists(_ == "true") {
      println("Debugging!")
    }
    

    如果您出于某种原因担心该语句甚至不应该出现在编译输出中,那么您可以使用带有编译时常量表达式的 if 块。在这些情况下,javac/scalac 将正确推断条件永远不会为真,因此甚至不包括块的字节码。 (显然你需要修改你的构建,为调试构建引入一个常量“true”,为 prod 构建引入一个常量“false”。)

    object Constants {
        final val DEBUG = false
    }
    
    // ...
    
    if (Constants.DEBUG) {
      println("Debugging!")
    }
    

    【讨论】:

    • final val DEBUG 或者它不是编译时常量。
    猜你喜欢
    • 2016-09-27
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    相关资源
    最近更新 更多