Scala 中如何获取函数名称?

2023-12-23

考虑一个简单的任务。只需显示整个表达式即可:

    a operator b = c

在 Common Lisp 中它可能看起来像这样:

    (defun applyOp (a b op) 
        (format t "~S ~S ~S = ~S" a op b (apply op (list a b))))

    $ (applyOp 1 2 #'logand)
    1 #<FUNCTION LOGAND> 2 = 0

在 Scala 中,这似乎并不那么微不足道:

    def applyOperator(x: Int, y: Int, op: (Int, Int) => Int) = { 
        println(x + s" $op " + y + " = " + op(x,y)) 
    }

    scala> applyOperator(1, 2, _ & _)
    1 <function2> 2 = 0 // how to get the function name? 

叫什么名字<function2>?


另一种全功能的方法是一个简单的macro http://docs.scala-lang.org/overviews/macros/overview.html.

假设您编写最简单的宏来提取表达式和类型名的字符串表示形式:

import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros

class VerboseImpl(val c: Context) {
  import c.universe._

  def describe[T: c.WeakTypeTag](expr: c.Expr[T]): c.Expr[(String, String, T)] = {
    val repr = expr.tree.toString
    val typeName = weakTypeOf[T].toString
    c.Expr[(String, String, T)](q"($repr, $typeName, $expr)")
  }

}

object Verbose{
  def apply[T](expr: T): (String, String, T) = macro VerboseImpl.describe[T]
}

接下来在另一个源(最好在另一个子项目中)你可以编写

val a = 2
val b = 3
println(Verbose(a + b + 3))

并看到神奇的字符串

(a.+(b).+(3),Int,8)

从现在起,您可以增强宏以显示有关方法、参数、类型等的任何信息...

请注意,宏是在编译时评估的。所以开销为Verbose.applycall 就像用两个字符串常量创建元组,因此虽然它是唯一的无样板、可扩展的方法,但它绝对是性能最高的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 中如何获取函数名称? 的相关文章

随机推荐