简体   繁体   中英

Class with covariant type parameter and private constructor in Scala

Here is an example from the stairway 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
        }
      }
    }

    // cannot resolve symbol U
    def this[U >: T](xs: U*) = this(xs.toList, Nil)
    // Covariant type T occurs in contra-variant position
    def this(xs: T*) = this(xs.toList, 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 size = leading.size + trailing.size
  }   
}

I added these lines:

    // cannot resolve symbol U
    def this[U >: T](xs: U*) = this(xs.toList, Nil)
    // Covariant type T occurs in contra-variant position
    def this(xs: T*) = this(xs.toList, Nil)

because I need some public constructors to create new Queues. But each of these constructors has its problems (see the comments). What can be done to solve them?


Update

A constructor with no parameters seems to compile fine:

def this() = this(Nil, Nil)

In Scala, the prefered alternative to multiple contructors is to have a companion object with apply methods:

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)
}

This way, you can instantiate your queues with val q = Queue(1, 2, 3) (note the absence of new ) as you would with most of the data structures in the Scala standard collection.

The object I wrote above will not compile as is because the two apply methods have same type after erasure, there are different ways around this issue, but in this precise example I think it's best to simply get ride of the second function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM