为什么Scala有时会忽略明确定义的类型?
发布时间:2020-12-16 10:06:06 所属栏目:安全 来源:网络整理
导读:所以这就是我在 Scala遇到的各种情况下遇到的问题 – 它似乎忽略了隐含的类型,即使情况很明显.当然,这可能是我承认的理解,但是当涉及到下划线的占位符时,我一直遇到麻烦.例如下面(这是虚构的,只是为了证明这一点).特征X的第二个位置必须是:X [,]某种类型.这
所以这就是我在
Scala遇到的各种情况下遇到的问题 – 它似乎忽略了隐含的类型,即使情况很明显.当然,这可能是我承认的理解,但是当涉及到下划线的占位符时,我一直遇到麻烦.例如下面(这是虚构的,只是为了证明这一点).特征X的第二个位置必须是<:X [,]某种类型.这里没有歧义 - 所以scala看到这个位置的任何地方,无论它的编码有多弱 - 联系人都是X,我应该可以访问像“doX”这样的函数.这不是无可争辩的吗?无论我在代码中处理那个位置有多糟糕,我都必须至少得到X.为什么当你深入到类型系统时,Scala会不断忽略这个事实?任何指针都将不胜感激,谢谢!
object TestRun extends App { trait X[T,Y<:X[_,_]] { def doesX:Unit def providesY:Y } class Test extends X[Int,Test]{ override def doesX: Unit = println("etc..") def providesY:Test = new Test } val a:X[_,_] = new Test //yes I know I could define a better here,its just to demo. I shouldn't have to explicitly relabel the 2nd _ as _<:X[_,<:X[ etc.. val b = a.providesY //clearly this has to be at least a (something) WITH X,but scala claims this as "Any" b.doesX //error won't compile!! //trait } 解决方法
当你写:
val a: X[_,_] = new Test ^ // This is treated as if the type parameter is Any,for the most part 您告诉编译器a是X,您不关心它的类型参数是什么.也就是说,假定无界通配符_具有Any的上限,就是这样. provideY使用X的第二个类型参数来确定其返回类型,但是对于编译器被告知丢弃它.所以b只是一个Any.使用REPL更容易看到: scala> val a: X[_,_] = new Test a: X[_,_] = Test@27abe2cd scala> val b = a.providesY b: Any = Test@f5f2bb7 因此,b.doesX无法编译,因为编译器现在认为它是Any.简单的解决方案是不要将通配符用于类型(或者通常是任何存在类型,大多数情况下你不需要这样). scala> val a: X[Int,Test] = new Test a: X[Int,Test] = Test@1134affc scala> val b = a.providesY b: Test = Test@6fc6f14e scala> b.doesX etc.. 或者你可以简单地省略类型注释,让编译器推断出正确的类型. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |