scala - 检查类型子类型时结果不一致
问题描述
有时,当我检查一个类是否扩展了一个特征时,我会得到不一致的结果。我正在使用 scala 2.12.8。
我的项目用于ru.Type
动态构建操作链。一个操作的输出必须符合下一个操作的输入。
在链接两个操作之前,我使用以下方法检查类型是否兼容:
def checkFrom(t: ru.Type): Boolean = t <:< ru.typeOf[ExpectedTrait[_, _, _]]
但有时(实际上很少)<:<
返回 false 而不是 true(我没有确定原因)。我添加了调试消息:
def checkFrom(t: ru.Type): Boolean = {
val expectedType = ru.typeOf[ExpectedTrait[_, _, _]]
val r = t <:< expectedType
if (!r) println(s"$t is not a $expectedType (${t <:< expectedType})")
r
}
我可以看到如下消息:MyClass is not a ExpectedTrait (true)
。第一次评估<:<
返回 false ,第二次返回 true !
t 是一个Types$ClassNoArtgsTypeRef
并且 expectedType 是一个Types$ExistentialType
--edit-1--
所有 ru.Type 都来自ru.typeOf[X]
. 在这种情况下,我不使用rm.classSymbol(x.getClass).toType
.
这个问题可能与inconsistency-with-scala-reflection-library有关
它是否存在解决方法?
--编辑-2--
我可以使用以下代码重现错误:
import scala.reflect.runtime.{universe => ru}
abstract class BaseClass[A, This <: BaseClass[A, This]](a: A) {
def newInstance(a: A): This
}
abstract class ExtClass[A, This <: ExtClass[A, This]](a: A) extends BaseClass[A, This](a)
class MyClass(n: Int) extends ExtClass[Int, MyClass](n) {
override def newInstance(a: Int): MyClass = new MyClass(a)
}
object ReflectionTest extends App {
def test[T: ru.TypeTag](tpe: ru.Type): Boolean = {
val r = tpe <:< ru.typeOf[T]
if (!r) println(s"test fails: ${tpe <:< ru.typeOf[T]}")
r
}
println((0 until 1000).par.forall(_ => test[BaseClass[_, _]](ru.typeOf[MyClass])))
}
我认为关键是并行执行。这是一个输出示例:
test fails: true
test fails: true
false
解决方案
推荐阅读
- javascript - Tampermonkey/Chrome:鼠标悬停,Ctrl+C → 复制超链接(原标题)
- python - 我如何解决这个十亿迭代和?欧拉计划问题 94,Python
- php - 已解决:LDAP 连接在 CLI 中正常,在 PHP-FPM 中失败
- r - 和 Brier Score 是评估此二项式 glm 模型的正确方法吗?
- reactjs - 使用 .push 更新组件
- exception - OCaml Streams:异常处理或选项类型?
- sql - 根据条件引用不同的表
- javascript - 反应:使div的宽度等于高度。高度计算不正确
- java - Java iText7 获取表格高度
- azure-cosmosdb - 过滤聚合函数