Class 在 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)
因为我需要一些 public 构造函数来创建新队列。但是这些构造函数中的每一个都有其问题(请参阅评论)。可以做些什么来解决它们?
更新
没有参数的构造函数似乎可以正常编译:
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)
}
通过这种方式,您可以使用 val q = Queue(1, 2, 3)
(注意缺少 new
)实例化队列,就像使用 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)
因为我需要一些 public 构造函数来创建新队列。但是这些构造函数中的每一个都有其问题(请参阅评论)。可以做些什么来解决它们?
更新
没有参数的构造函数似乎可以正常编译:
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)
}
通过这种方式,您可以使用 val q = Queue(1, 2, 3)
(注意缺少 new
)实例化队列,就像使用 Scala 标准集合中的大多数数据结构一样。
我上面写的对象不会按原样编译,因为擦除后两个应用方法具有相同的类型,解决这个问题有不同的方法,但在这个精确的例子中我认为最好简单地使用第二个功能。