@specialized Nach dem Specialized SID Section 3.1:
Not all members of a class are specialized. Currently, specialized variants of a member m are created only when m’s type contains at least one specialized naked type parameter, or an array of a naked specialized type parameter.
Normalerweise dies keinen Unterschied machen könnte, aber es funktioniert hier. Dies liegt daran, wenn Sie ResizeableArray
für Int
spezialisieren, der Compiler eine andere Klasse wie folgt erzeugt (beachten Sie, dass var capacity
nicht da ist):
<specialized> class ResizeableArray$mcI$sp extends ResizeableArray {
implicit <paramaccessor> private val evidence$1: scala.reflect.Manifest = _;
<specialized> protected[this] var arr$mcI$sp: Array[Int] = _;
<accessor> <specialized> protected def arr$mcI$sp(): Array[Int] = ResizeableArray$mcI$sp.this.arr$mcI$sp;
override <accessor> <specialized> protected def arr(): Array[Int] = ResizeableArray$mcI$sp.this.arr$mcI$sp();
<accessor> <specialized> protected def arr$mcI$sp_=(x$1: Array[Int]): Unit = ResizeableArray$mcI$sp.this.arr$mcI$sp = x$1;
override <accessor> <specialized> protected def arr_=(x$1: Array[Int]): Unit = ResizeableArray$mcI$sp.this.arr$mcI$sp_=(x$1);
def specInstance$(): Boolean = true;
override <bridge> <specialized> <artifact> protected def arr_=(x$1: Object): Unit = ResizeableArray$mcI$sp.this.arr_=(x$1.$asInstanceOf[Array[Int]]());
override <bridge> <specialized> <artifact> protected def arr(): Object = ResizeableArray$mcI$sp.this.arr();
<specialized> def <init>(initialCapacity: Int, evidence$1: scala.reflect.Manifest): ResizeableArray$mcI$sp = {
ResizeableArray$mcI$sp.this.evidence$1 = evidence$1;
ResizeableArray$mcI$sp.super.<init>(initialCapacity, evidence$1);
ResizeableArray$mcI$sp.this.arr$mcI$sp = scala.Array.ofDim(ResizeableArray$mcI$sp.this.initialCapacity(), evidence$1).$asInstanceOf[Array[Int]]();
()
}
}
Durch die obige Definition nur die Mitglieder, die den speziellen Parameter in irgendeiner Weise enthalten in der Implementierung von ResizeableArray$mcI$sp
übersteuert werden. Das bedeutet, dass capacity
in der spezialisierten Klasse nicht überschrieben oder implementiert wird. Daher erwartet der Compiler, dass er stattdessen bei Bedarf vererbt wird. Leider ist capacity
privat, es wird nicht vererbt und Sie erhalten einen Compilerfehler. Ich weiß nicht, ob private Mitglieder hier übersehen oder bewusst ausgeschlossen wurden, aber Sie müssen vorsichtig sein, wenn Sie sie in speziellen Klassen verwenden.
In diesem Fall ist eine einfache Behelfslösung tun:
class ResizeableArray[@specialized(Int) T: Manifest](initialCapacity: Int) {
private var capacity = initialCapacity
private var arr = Array.ofDim[T](initialCapacity)
}
Der einzige andere Weg, um dies wäre capacity
öffentlich zu machen, was sicherlich würden Sie hier nicht wollen, aber in akzeptabel sein kann andere Fälle (wenn es nicht veränderbar ist).
Ich bemerkte auch, dass durch Entfernen von privat verschwindet die Fehlermeldung, aber kann nicht herausfinden, warum. Sie sagen, dass Array nicht spezialisiert ist, Sie meinen, dass ich für die primitive Variante nicht das Java-Äquivalent von int [Kapazität] bekomme und es immer noch Objekt [Kapazität] sein wird? – Wickoo