繁体   English   中英

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

[英]How to compare the return type of a method to a Scala native or TypeTag?

因此,我正在使用 Scala 反射库,并且我正在尝试检查方法是否符合给定类型。 为了简化,我试图只检查它的 output。

我现在拥有的是:

val returnType = methodSymbol.returnType
// returnType: reflect.runtime.universe.Type = java.lang.String

所以,我可以读到它是一个字符串,但它有这种可怕的类型reflect.runtime.universe.Type 我到底如何比较检查这个返回类型是否是一个简单的字符串? 我什至尝试使用很简单的 TypeTag,但是将Type转换为TypeTag是一项巨大的努力,我不相信这样简单的任务无法用更简单的方式完成。

那么,我怎样才能将其与字符串进行比较并简单地返回 boolean 呢? 我想简单地调用一个toString()并尝试将其解析回正常类型,但这在代码上真的很恶心,IMO。 另外,我不能简单地指定方法名称,因为我正在处理一个方法列表,以后还会有更多。

我已经看到了一些问题,甚至这个(在我看来,非常复杂)关于如何将 Type 转换为 TypeTag 的答案,但是,我再次对如此微不足道的任务的复杂程度感到困惑。 我已经在考虑拔掉我稀少的头发了。 帮助表示赞赏。

编辑:我已经设法对字符串本身进行了比较,但没有对返回字符串的方法进行比较。

为了比较 String 返回类型,我正在做:

val returnType = methodSymbol.returnType
returnType =:= typeTag[String].tpe

但是,当我尝试使用 inheritance 和一种方法检查它时,使用<:< ,它不起作用。 澄清一下, B 扩展了 Trait A,类型签名是() => B ,但我在编码时无法匹配

val typeSig = methodSymbol.typeSig
typeSig <:< typeTag[() => A].tpe

如果您想将类型作为String使用,您应该解析它们

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

(我只想做tb.typecheck(tb.parse(str/*, mode =???*/), mode = tb.TYPEmode).tpe但找不到如何在运行时调用TypeParser而不是TermParser反射,这对应于tq"..."q"..."之间的区别,否则我会得到String伴侣而不是String本身。当然tq"$str"也会给出错误的类型,因为它是一个宏,它只能工作对于编译时文字: tq"java.lang.String" 。)

也许不完全符合您的要求,但您可以在 Scala 中使用java.lang.reflect

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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM