【问题标题】:Scala type boundsScala 类型边界
【发布时间】:2013-12-30 15:39:03
【问题描述】:

下面的代码有什么问题?我在指示的行上从编译器收到以下投诉:类型参数 [Asset] 不符合 trait Worker 的类型参数界限 [T <: br.>

这是怎么回事? Worker 需要一个 Doable 的子类型,而资产扩展 Doable。

trait Doable

trait Worker[T<:Doable] {
  def hey():String
}

case class Asset() extends Doable

case class Hey[Asset] extends Worker[Asset] { // << error here
  def hey() = "You!"
}

【问题讨论】:

  • 案例类声明中的类型参数搞砸了,case class Hey() extends Worker[Asset] { def hey() = "You!" } 工作得很好。至于为什么,不知道,虽然我并没有真正考虑过,老实说:)
  • case class Hey[Asset] extends Worker[Asset] 和 case class Hey[T] extends Worker[T] 含义相同。 Asset 这里只是 Hey 类的类型参数的新名称。见stackoverflow.com/a/19137992/406435

标签: scala


【解决方案1】:

当你声明case class Hey[Asset] 时,你绑定了一个新的类型变量Asset,你没有引用case class Asset() extends Doable(你正在隐藏Asset 类型变量)。 您的代码相当于:

  case class Hey[A] extends Worker[A] {
    ...
  }

这显然行不通。

【讨论】:

    【解决方案2】:

    问题是您使用相同的值Asset 来引用案例类和类型参数,这让您感到困惑。

    你可能打算这样做:

    case class Hey[T](str: String) extends Worker[Asset] { 
      def hey() = "You!"
    }
    

    虽然这不是重点,但请注意我向Hey 添加了一个参数,因为不推荐使用没有参数的案例类。

    【讨论】:

      【解决方案3】:

      这个问题已经被问过很多次了,如果你看到类型参数和构造函数参数之间的类比,我认为混淆很容易消失,将它们视为不同类型的构造函数参数:类型级别和值-等级。

      免责声明 当然,这只是一个类比,它会在很多不同的层面上崩溃,并且与任何 Scala 一样存在很多极端情况;但我的意思是它可能是有用的

      在类型级别,您可以将&lt;: 视为在值级别上等同于::

      class TypeParamsVsVals {
      
        type X
        type X1 <: X
      
        class Buh[T <: X]
        class Oh[T1 <: X1] extends Buh[T1]
        // wait for Scala 3
        // class Oh[T1 <: X1] extends Buh[T = T1]
      
        type x
        type x1 <: x
      
        class buh(val t: x)
        class oh(val t1: x1) extends buh(t = t1)
      }  
      

      我认为混淆的主要来源是在类型级别上,&lt;: 的两侧之间没有任何区别,更糟糕的是,您可以编写 T 而没有任何(没有双关语)限制,而您不能在价值级别上做同样的事情:

      class NoBounds[T]
      // same as 
      class AltNoBounds[T <: Any]
      
      // you cannot write
      // class noBounds(val t)
      class noBounds(val t: Any)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-25
        • 2021-01-24
        • 2020-07-22
        • 2013-05-31
        • 1970-01-01
        • 1970-01-01
        • 2018-08-18
        • 2020-10-14
        相关资源
        最近更新 更多