加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么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..

或者你可以简单地省略类型注释,让编译器推断出正确的类型.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读