Можно ли восстановить имя функции изнутри функции в Scala?
Я хотел бы сделать что-то вроде
def getMeASammy() {println "getMeASammy"}
def getMeADrink() {println "getMeADrink"}
def getMeASub() {println "getMeASub"}
Но я не хочу явно набирать имя функции.
2 ответа
scala> def currentMethodName() : String = Thread.currentThread.getStackTrace()(2).getMethodName
currentMethodName: ()String
scala> def getMeASammy() = { println(currentMethodName()) }
getMeASammy: ()Unit
scala> getMeASammy()
getMeASammy
Nameof делает именно это и во время компиляции, поэтому нет создания исключений, проверки трассировки стека и других накладных расходов, связанных с отражением.
Соответствующий пример из файла readme:
import com.github.dwickern.macros.NameOf._
def startCalculation(value: Int): Unit = {
println(s"Entered ${nameOf(startCalculation _)}")
}
// compiles to:
def startCalculation(value: Int): Unit = {
println(s"Entered startCalculation")
}
В твоем случае
def getMeASammy() = println(nameOf(getMeASammy _))
Также, nameOf
работает с классами, атрибутами классов, типами и т. д.
Это несколько отвратительно, но единственный поддерживаемый способ получить имя текущего метода от JVM - создать исключение (но не выбросить его), а затем прочитать имя метода из трассировки стека исключения.
def methodName:String= new Exception().getStackTrace().apply(1).getMethodName()
Я написал простую библиотеку, которая использует макрос для получения имени функции. Это может быть более элегантное решение, чем использованиеThread.currentThread.getStackTrace()(2).getMethodName
если вы не против дополнительной зависимости:
libraryDependencies += "com.github.katlasik" %% "functionmeta" % "0.2.3" % "provided"
import io.functionmeta._
def getMeASammy() {
println(functionName) //will print "getMeASammy"
}