Luc*_*ima 2 reflection scala scala-reflect
所以,我正在使用 Scala 反射库,并且我正在尝试检查一个方法是否符合给定的类型。为简化起见,我试图仅检查其输出。
我现在拥有的是:
val returnType = methodSymbol.returnType
// returnType: reflect.runtime.universe.Type = java.lang.String
Run Code Online (Sandbox Code Playgroud)
所以,我可以读到它是一个字符串,但它有这种可怕的类型reflect.runtime.universe.Type。我到底如何比较检查这个返回类型是否是一个简单的字符串?我什至尝试使用足够简单的 TypeTags,但是将 a 转换Type为 aTypeTag是一项巨大的努力,我不相信这样简单的任务无法通过更简单的方式完成。
那么,我如何将它与 String 进行比较并简单地返回一个布尔值?我想简单地调用 atoString()并尝试将其解析回正常类型,但这对代码来说真的很恶心,IMO。此外,我不能简单地指定方法名称,因为我正在处理方法列表,稍后会提供更多方法。
我已经看到了一些问题,甚至这个(在我看来,荒谬复杂的)回答有关如何将类型转换为TypeTag,但同样,我被复杂的这样一个简单的任务级别百思不得其解。我已经在考虑拔掉我稀少的头发了。帮助表示赞赏。
编辑:我已经设法对字符串本身进行比较,但没有对返回字符串的方法进行比较。
为了比较 String 返回类型,我正在做:
val returnType = methodSymbol.returnType
returnType =:= typeTag[String].tpe
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用继承和方法检查它时,使用<:<,它不起作用。澄清一下,B 扩展了 Trait A,类型签名是() => B,但我在编码时无法匹配
val typeSig = methodSymbol.typeSig
typeSig <:< typeTag[() => A].tpe
Run Code Online (Sandbox Code Playgroud)
如果你想使用类型作为Strings 你应该解析它们
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val str = "java.lang.String"
val tpe: Type = (tb.typecheck(tb.parse(s"type T = $str"), mode = tb.TYPEmode) match {
case q"type T = $typ" => typ
}).tpe // String
tpe =:= typeOf[String] //true
Run Code Online (Sandbox Code Playgroud)
(我想做只是tb.typecheck(tb.parse(str/*, mode = ???*/), mode = tb.TYPEmode).tpe但找不到如何调用TypeParser而不是TermParser运行时反射,这对应于tq"..."and之间的差异q"...",否则我会得到String同伴而不是String它自己。当然tq"$str"也会给出错误的类型,因为它是一个宏,它只能工作对于编译时文字:tq"java.lang.String".)
也许不完全是您所要求的,但您可以java.lang.reflect在 Scala 中使用。
import java.lang.reflect.Method
class C {
def doSomething(): String = {
return "hello"
}
def doSomethingElse(): String = {
return "bye"
}
def doNothing(): Int = {
return 190
}
}
val doSomethingMethod: Method = classOf[C].getMethods()(2)
val doNothingMethod: Method = classOf[C].getMethods()(1)
val doSomethingElseMethod: Method = classOf[C].getMethods()(0)
// false
doSomethingMethod.getReturnType.equals(doNothingMethod.getReturnType)
// true
doSomethingMethod.getReturnType.equals(doSomethingMethod.getReturnType)
// you can compare the simple name, too, if that's easier
println(s"'${doSomethingMethod.getReturnType.getSimpleName}'")
// 'String'
Run Code Online (Sandbox Code Playgroud)