Scala 下限是如何工作的?

Scala 下限是如何工作的?,scala,Scala,我已经尽力去理解lowerbound在类型参数化中是如何工作的,但是我不能清楚地理解它 下面是lowerbound的一些示例代码 class Queue[+T] ( private val leading: List[T], private val trailing: List[T] ) { private def mirror = { if (leading.isEmpty){ new Queue(trailing.reverse, Nil) }

我已经尽力去理解lowerbound在类型参数化中是如何工作的,但是我不能清楚地理解它

下面是lowerbound的一些示例代码

class Queue[+T] (
  private val leading: List[T],
  private val trailing: List[T]
) {

  private def mirror = {
    if (leading.isEmpty){
      new Queue(trailing.reverse, Nil)
    }
    else
      this
  }

  def head = mirror.leading.head

  def tail = new Queue(mirror.leading.tail,
                       mirror.trailing)

  /* ====Wrong definition for enqueue====
   * def enqueue (item: T) =
   *   new Queue(leading, item :: trailing)
   */

  def enqueue[U >: T] (item: U) =
    new Queue[U](leading, item :: trailing)
}

class Fruit (val name: String) {
  override def toString = name
}
class Orange extends Fruit("orange")
class Apple  extends Fruit("apple")

val queueOrange: Queue[Orange] = new Queue[Orange](Nil, Nil)
queueOrange.enqueue(new Apple())
queueOrange.enqueue(new Orange())
queueOrange.enqueue(new Fruit("PineApple"))

val queueFruit: Queue[Fruit] = queueOrange
queueFruit.enqueue(new Orange())
queueFruit.enqueue(new Apple())
queueFruit.enqueue(new Fruit("Pineapple"))
并且是执行上述代码的结果

我有一些与上述代码和结果相关的问题

  • 我无法理解queueOrange.enqueue(新的Apple())代码是如何成功执行的。据我所知,lowerbound限制enqueue方法中的类型U应该是T的超类型,T是lowerbound。然而,在这里苹果和橘子是兄弟姐妹,它们扩展了相同的超类水果

  • 我无法理解queueOrange.enqueue(new Apple())如何返回队列[Fruit],即使我们将新的Orange()作为enqueue的参数输入。我认为这是可能的,因为橘子继承了水果,但我不明白允许问题1和问题2发生的整体机制是如何运作的

  • 当我在上面的代码中使用queueOrange和queueFruit做同样的事情时,我无法理解为什么结果会不同

  • 据我所知,lowerbound限制enqueue方法中的类型
    U
    应该是
    T

    这不是完整的定义
    U
    ,或其任何祖先必须是
    T
    的超类型。如果我们将该表达式赋给一个值,您将看到推断的类型是
    Queue[Fruit]
    ,因为编译器足够聪明,可以查看对象图

    如果要确保
    U
    T
    的直接超类型,需要稍微修改一下方法:

    def enqueue[U](u: U)(implicit ev: T <:< U)
    
    def排队[U](U:U)(隐式ev:T橙色)将失败


    谢谢你的回答,但我很好奇为什么兄弟苹果可以被视为Orange的超类型?编译器会自动从苹果中推断出类型Fruit并将其应用到U吗?我不确定这是怎么发生的……我读了你提到的文章,但我认为最后一个例子只与我考试的最后一部分相匹配ple代码,即val queueFruit:Queue[Fruit]=queueOrange.谢谢!@Jaehuk Lee它不是被视为超类型的
    Apple
    。当编译器尝试绑定
    U
    时,它将在
    Apple
    上失败,并开始搜索类型层次结构以寻找合适的匹配项,直到它到达
    Fruit
    。哦,我知道编译器何时发现Apple不是橙色,然后它尝试查看Apple的超类,看看Apple类是否有任何可匹配的橙色超类型。是这样吗?现在一切都很清楚了。谢谢:多谢!!!如果你不介意,你能帮我解决这个问题吗??