[英]How to compare the return type of a method to a Scala native or TypeTag?
So, I'm using the Scala reflections library, and I'm trying to check if a method conforms to a given type.因此,我正在使用 Scala 反射库,并且我正在尝试检查方法是否符合给定类型。 To simplify, I'm trying to check only its output.
为了简化,我试图只检查它的 output。
What I have now is:我现在拥有的是:
val returnType = methodSymbol.returnType
// returnType: reflect.runtime.universe.Type = java.lang.String
So, I can read it is a String, but it has this terrible type reflect.runtime.universe.Type
.所以,我可以读到它是一个字符串,但它有这种可怕的类型
reflect.runtime.universe.Type
。 How on Earth can I compare check if this return type is a simple String?我到底如何比较检查这个返回类型是否是一个简单的字符串? I even tried using TypeTags, which are simple enough, but to convert a
Type
to a TypeTag
is such a monumental effort that I fail to believe such a simple task cannot be achieved with more simply.我什至尝试使用很简单的 TypeTag,但是将
Type
转换为TypeTag
是一项巨大的努力,我不相信这样简单的任务无法用更简单的方式完成。
So, how can I compare this to a String and simply get a boolean back?那么,我怎样才能将其与字符串进行比较并简单地返回 boolean 呢? I thought of simply calling a
toString()
and trying to parse that back to a normal type, but that would be really disgusting to do on the code, IMO.我想简单地调用一个
toString()
并尝试将其解析回正常类型,但这在代码上真的很恶心,IMO。 Also, I cannot simply specify the method name, because I'm working on a list of methods, and more will come later.另外,我不能简单地指定方法名称,因为我正在处理一个方法列表,以后还会有更多。
I've seen some questions, and even this (in my opinion, absurdly complex) answer on how to convert a Type to a TypeTag, but, again, I'm baffled by the level of complexity for such a trivial task.我已经看到了一些问题,甚至这个(在我看来,非常复杂)关于如何将 Type 转换为 TypeTag 的答案,但是,我再次对如此微不足道的任务的复杂程度感到困惑。 I'm already thinking of pulling my scarce hair out.
我已经在考虑拔掉我稀少的头发了。 Help appreciated.
帮助表示赞赏。
EDIT: I've managed to make the comparison for the String itself, but not for a method returning the String.编辑:我已经设法对字符串本身进行了比较,但没有对返回字符串的方法进行比较。
To compare the String return type, I'm doing:为了比较 String 返回类型,我正在做:
val returnType = methodSymbol.returnType
returnType =:= typeTag[String].tpe
When I try to check it with inheritance and a method, though, using <:<
, it won't work.但是,当我尝试使用 inheritance 和一种方法检查它时,使用
<:<
,它不起作用。 To clarify, B extends Trait A, the type signature is () => B
, but I cannot match when coding澄清一下, B 扩展了 Trait A,类型签名是
() => B
,但我在编码时无法匹配
val typeSig = methodSymbol.typeSig
typeSig <:< typeTag[() => A].tpe
If you want to work with types as String
s you should parse them如果您想将类型作为
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
(I would like to do just tb.typecheck(tb.parse(str/*, mode =???*/), mode = tb.TYPEmode).tpe
but can't find how to call TypeParser
instead of TermParser
with runtime reflection, this corresponds to difference between tq"..."
and q"..."
, otherwise I get String
companion instead of String
itself. Surely tq"$str"
gives wrong type too because it's a macro, it can work only for compile-time literals: tq"java.lang.String"
.) (我只想做
tb.typecheck(tb.parse(str/*, mode =???*/), mode = tb.TYPEmode).tpe
但找不到如何在运行时调用TypeParser
而不是TermParser
反射,这对应于tq"..."
和q"..."
之间的区别,否则我会得到String
伴侣而不是String
本身。当然tq"$str"
也会给出错误的类型,因为它是一个宏,它只能工作对于编译时文字: tq"java.lang.String"
。)
Maybe not exactly what you're asking for, but you can use java.lang.reflect
in Scala.也许不完全符合您的要求,但您可以在 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.