2015-09-26 32 views
1

下面是从楼梯书(有一些修改)的例子:为什么我从这段代码中得到Queue [Nothing]而不是Queue [Book]?

object Example { 
    class Queue[+T] private (
          private[this] var leading: List[T], 
          private [this] var trailing: List[T] 
          ) { 
    private def mirror: Unit = { 
     if(leading.isEmpty) { 
     while(!trailing.isEmpty) { 
      leading = trailing.head :: leading 
      trailing = trailing.tail 
     } 
     } 
    } 

    def this() = this(Nil, Nil) 

    def head: T = { 
     mirror 
     leading.head 
    } 

    def tail: Queue[T] = { 
     mirror 
     new Queue(leading.tail, trailing) 
    } 

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

    def enqueue[U >: T](xs: U*) = new Queue[U](leading, xs.reverse.toList ::: trailing) 

    def size = leading.size + trailing.size 
    } 

    object Queue { 
    def apply[T, U <: T](xs: U*): Queue[T] = new Queue(xs.toList, Nil) 
    def apply[T]: Queue[T] = new Queue[T](Nil, Nil) 
    } 

    class Publication 
    class Book extends Publication 
    class Novel extends Book 
    class Journal extends Publication 
    class Magazine extends Publication 

} 

object Test { 

    import Example._ 
    { 
    val q = new Queue[Int]() 
    val q1 = q.enqueue[Int](1, 2, 3) 
    q1.head // 1 
    val p = Queue(new Book, new Book, new Book) // Queue[Nothing] ? 
    } 
} 

我得到的类型Queue[Nothing]p从这一行:

val p = Queue(new Book, new Book, new Book) // Queue[Nothing] ? 

我期待一个Queue[Book]。编译器如何得出这个结论,我该如何解决这个问题?

回答

1

类型参数混淆了类型推断,我认为是因为第二个构造函数参数Nil。只使用一种类型参数T

object Queue { 
    // def apply[T, U <: T](xs: U*): Queue[T] = new Queue(xs.toList, Nil) 
    def apply[T](xs: T*): Queue[T] = new Queue(xs.toList, Nil) 

    def apply[T]: Queue[T] = new Queue[T](Nil, Nil) 
    } 

这是它是如何工作现在:

val b1 = new Book 
val b2 = new Magazine 
val b3 = new Journal 
val p = Queue(b1, b2, b3) // Example.Queue[Example.Publication] 

这个推断正确的类型为Publication

相关问题