在Scala 2.9.x中,我编写了func函数,它返回了函数的名称,其中func()的执行方式与FUNC C预处理器宏类似.据我所知,在Scala2.10中,我应该能够写一些比抛出异常更优雅的东西来完成这项工作.
我该怎么做?在此先感谢您的帮助.
object TestMyLog extends App {
val MatchFunc = """(.+)\(.+""".r
def func(i_level: Int): String = {
val s_rien = "functionNotFound"
try {
throw new Exception()
} catch {
case unknwn => unknwn.getStackTrace.toList.apply(i_level).toString match {
case MatchFunc(funcs) => funcs.split('.').toList.last
case _ => s_rien
}
} finally {
s_rien
}
}
def tracedFunction1 = func(1)
def tracedFunction2 = func(1)
println(tracedFunction1)
assert(tracedFunction1=="tracedFunction1")
println(tracedFunction2)
assert(tracedFunction2=="tracedFunction2")
}
Run Code Online (Sandbox Code Playgroud)
import scala.reflect.macros.Context
import scala.language.experimental.macros
def impl(c: Context) = {
import c.universe._
c.enclosingMethod match {
case DefDef(_, name, _, _, _, _) =>
c.universe.reify(println(c.literal(name.toString).splice))
case _ => c.abort(c.enclosingPosition, "no enclosing method")
}
}
scala> def printEnclosingMethod = macro impl
defined term macro printEnclosingMethod: Unit
scala> def foo = printEnclosingMethod
foo: Unit
scala> foo
foo
scala> printEnclosingMethod
<console>:32: error: no enclosing method
printEnclosingMethod
^
Run Code Online (Sandbox Code Playgroud)
我不确定是否会在没有异常的情况下执行此操作,但实际上您不需要抛出/捕获异常来获取堆栈跟踪:
(new Exception).getStackTrace.toList
Run Code Online (Sandbox Code Playgroud)