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

为什么scalac不相信某个方法不符合所需的类型签名?

发布时间:2020-12-16 08:54:05 所属栏目:安全 来源:网络整理
导读:为什么这不编译? 给出的错误是类SomeElement需要是抽象的,因为特征元素中的方法eval类型为[Tlt ;:Typed] = scala.util.Try [T]未定义 我无法理解为什么在SomeElement上定义的方法eval不满足类型约束. 据我所知,eval应该返回一个包含在Try中的东西,其中包含T
为什么这不编译?
给出的错误是类SomeElement需要是抽象的,因为特征元素中的方法eval类型为[T&lt ;:Typed] => scala.util.Try [T]未定义

我无法理解为什么在SomeElement上定义的方法eval不满足类型约束.

据我所知,eval应该返回一个包含在Try中的东西,其中包含Typed.
Try在其类型参数中是协变的. SomeElement中eval的实现返回NumberLike和NumberLike的子类.出了什么问题?

import scala.util.Try

trait Element {
   def eval[T <: Typed]: Try[T]
}

trait Typed

case class NumberLike(n: Long) extends Typed

case class SomeElement(n: Long) extends Element {
  def eval = Try {
    NumberLike(n)
  }
}

object app extends Application {
  println (SomeElement(5).eval)
}

尝试在SomeElement中向eval添加显式类型参数也无济于事:

case class SomeElement(n: Long) extends Element {
  def eval[NumberLike] = Try {
    NumberLike(n)
  }
}

将SomeElement的定义更改为上面给出:

found   : <empty>.NumberLike
  required: NumberLike(in method eval)
    NumberLike(n)

编辑我真的想知道为什么这不编译.问题的解决方法很有帮助,但我真的想知道这里发生了什么.

解决方法

类型参数T在函数上定义,而不是在封闭类型元素上定义,它不能通过继承“擦除”,并且必须保留在重写函数( http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#class-members)上.

将type参数移动到Element定义使其工作如下.

trait Element[T <: Typed] {
   def eval: Try[T]
}

trait Typed

case class NumberLike(n: Long) extends Typed

case class SomeElement(n: Long) extends Element[NumberLike] {
  def eval = Try {
    NumberLike(n)
  }
}

或使用类型成员:

trait Element {
   type T <: Typed
   def eval: Try[T]
}

trait Typed

case class SomeElement(n: Long) extends Element {
  type T = NumberLike
  def eval = Try {
    NumberLike(n)
  }
}

(编辑:李大同)

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

    推荐文章
      热点阅读