如何将方法的返回类型与 Scala 本机或 TypeTag 进行比较?

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)

Dmy*_*tin 5

如果你想使用类型作为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".)


ELi*_*nda 5

也许不完全是您所要求的,但您可以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)