繁体   English   中英

Scala中具有协变类型参数和私有构造函数的类

[英]Class with covariant type parameter and private constructor in Scala

这是楼梯书的示例:

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

我添加了以下几行:

    // 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 this() = this(Nil, Nil)

在Scala中,多个构造函数的首选替代方法是使用apply方法创建一个伴随对象:

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

这样,您可以像使用Scala标准集合中的大多数数据结构一样,使用val q = Queue(1, 2, 3) (注意缺少new )实例化队列。

我上面编写的对象不会按原样编译,因为擦除后这两个apply方法的类型相同,解决此问题的方式也不同,但是在这个精确的示例中,我认为最好简单地使用第二个函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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