2013-05-29 29 views
4

在C++中我可以寫(相當於#ifdef來?):斯卡拉:代碼僅在調試時運行

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

是否有任何斯卡拉相當於?

+2

可能重複http://stackoverflow.com/questions/12044054/debug-log-對性能沒有影響) – senia

+0

順便說一句,JVM和JIT通常在刪除死代碼方面做得非常好,因此很可能是簡單的'final val DEBUG = false'和'def log(str:String )= if(DEBUG)print(str)'應該足夠用於大多數情況。 –

回答

-1

如果你想要的代碼僅是執行當某些條件成立,則可以使用一個標準,如果塊:

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

如果您擔心無論出於何種原因,該聲明不應該連出現在編譯後的輸出中,那麼你可以使用帶有編譯時常量表達式的if塊。在這些情況下,javac/scalac會正確地推斷出該條件永遠不會成立,所以甚至不包括該塊的字節碼。 (當然你需要修改生成的常數「真」拉的調試版本,而「假」爲督促建立。)

object Constants { 
    final val DEBUG = false 
} 

// ... 

if (Constants.DEBUG) { 
    println("Debugging!") 
} 
+4

'最終val DEBUG'或它不是編譯時常量。 –

6

一個ç預處理程序的等價形式的#ifdef是一個斯卡拉宏

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中的任何內容都會進入結果字節代碼 其他代碼運行在編譯時間。如果(上)...,這特別適用於