Я заметил, что ScalaDoc для неизменяемого стека относится к методу, предваряющему следующую подпись:
class Stack[A+] ...
def +: (elem: A): Stack[A]
Эта сигнатура метода выглядела неправильно для меня, поскольку стек является ковариантным в параметре типа A (поэтомуэлемент должен быть ошибкой компилятора).Более того, Scaladoc говорит, что определение этого метода в GenSeqLike, но его там нет.
В SeqLike есть реализация +: я думаю, что именно она используется в Stack.
trait SeqLike[+A, +Repr] ...
def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
b += elem
b ++= thisCollection
b.result
}
Это выглядит не так эффективно, как Stack.push.
Когда я пытаюсь предоставить собственную реализацию +: (как push), я получаю ожидаемый компиляторошибок, которых нет в методе, который я переопределяю, и о проблеме ковариации.
class Stack2[+A] extends Stack[A] {
override def +: (elem: A): Stack[A] = this push elem
}
scalac Stack2.scala дает:
Stack2.scala:4: error: method +: overrides nothing
override def +: (elem: A): Stack[A] = this push elem
^
Stack2.scala:4: error: covariant type A occurs in contravariant position in type A of value elem
override def +: (elem: A): Stack[A] = this push elem
^
two errors found
Возможно ли реализовать +: эффективноиспользуя толчок?