Scala是否与GCC的typeof
extension等效? (还是C ++ decltype
?)
我正在生成引用一些外部代码(可能尚不可用)的代码,并且我需要一种方法来在方法定义中引用该代码的类型
对于单例对象,我可以使用Foo.type
,但是如果Foo
是一个任意表达式,则不起作用。
更新:
这是一个显示问题的简化示例:
def f(x: typeof(Foo))(implicit M: Monoid[typeof(Foo)]) =
M.append(Foo, M.append(x, Foo))
我正在处理的代码对Foo
一无所知,只是它是Scala表达式的字符串表示形式。它将上面的代码输出到.scala
文件中,以后将作为单独项目的一部分进行编译。
当然typeof(Foo)
位不起作用。仅当Foo.type
是单身人士时,才能使用Foo
。
基本上,我想知道是否有可以代替typeof(Foo)
的东西可以用于任意Scala表达式。
答案 0 :(得分:2)
在Scala中没有这种typeof
。
我们可以尝试修改添加类型参数的方法
def f[F](foo: F)(x: F)(implicit M: Monoid[F]) =
M.append(foo, M.append(x, foo))
像f(Foo)(...)
那样调用它,其中Foo
是要替换的表达式,然后应在编译时推断出F
。
否则,我可以想象以下工作流程。我们可以使用Scalameta的SemanticDB从Foo
本身的字符串表示形式生成表达式Foo
类型的字符串表示形式,然后插入表达式Foo
的字符串表示形式,并由此生成字符串表示形式类型。
另一种选择是使用macro annotation
生成树import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class generate(foo: String) extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro generateMacro.impl
}
object generateMacro {
def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
val str: String = c.prefix.tree match {
case q"new generate($s)" => c.eval[String](c.Expr(s))
}
val tree = c.typecheck(c.parse(str))
val tpe = tree.tpe.widen
annottees match {
case q"$mods def $name[..$_](...$_): $_ = $_" :: _ =>
q"""
$mods def $name(x: $tpe)(implicit M: Monoid[$tpe]): $tpe =
M.append($tree, M.append(x, $tree))
"""
}
}
}
@generate("1 + 1")
def f(): Unit = ()
// def f(x: Int)(implicit M: Monoid[Int]): Int = M.append(2, M.append(x, 2))
https://github.com/travisbrown/type-provider-examples/
https://docs.scala-lang.org/overviews/macros/typeproviders.html
实际上我想这与要求的很接近
class TypeOf[A](a: A) {
type T = A
}
val tp = new TypeOf(Foo)
def f(x: tp.T)(implicit M: Monoid[tp.T]) = M.append(Foo, M.append(x, Foo))
答案 1 :(得分:0)
您是否有要使用的类型的引用类?否则定义一个自定义类,并使用:
classOf [Class_Name]
等同于typeOf
如果您想了解自定义对象的类,请使用:
object_name.getClass