Generische Scala-Methode - Für T ist kein ClassTag verfügbar

73

Ich bin relativ neu in Scala und versuche, eine generische Objektmethode zu definieren. Wenn ich mich jedoch auf den parametrisierten Typ innerhalb der Methode beziehe, erhalte ich "Kein ClassTag für T verfügbar". Hier ist ein erfundenes Beispiel, das das Problem veranschaulicht.

scala> def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
<console>:7: error: No ClassTag available for T
       def foo[T](count: Int, value: T): Array[T] = Array.fill[T](count)(value)
                                                                        ^

Vielen Dank im Voraus für Ihre Hilfe, um zu verstehen, was hier falsch ist und wie dieses erfundene Beispiel funktioniert.

Futter
quelle

Antworten:

89

Um ein Array in einem generischen Kontext zu instanziieren (ein Array zu instanziieren, in Tdem Tsich ein Typparameter befindet), muss Scala zur Laufzeit über Informationen Tin Form eines impliziten Wertes vom Typ verfügen ClassTag[T]. Konkret muss der Aufrufer Ihrer Methode diesen ClassTagWert (implizit) übergeben , was bequem über eine Kontextbindung erfolgen kann :

def foo[T:ClassTag](count: Int, value: T): Array[T] = Array.fill[T](count)(value)

Eine (gründliche) Beschreibung dieser Situation finden Sie in diesem Dokument:

https://docs.scala-lang.org/sips/scala-2-8-arrays.html

(Um es kurz zu machen: ClassTags sind die überarbeitete Implementierung von ClassManifests, daher bleibt die Begründung erhalten.)

Régis Jean-Gilles
quelle
13
Faszinierend. Mit 'import scala.reflect.ClassTag' funktioniert dies. Vielen Dank.
Chuck
3
Die Leute finden das vielleicht auch lehrreich - docs.scala-lang.org/overviews/reflection/… - da ClassManifests weggehen.
Chuck
Wenn wir zwei Werte vom Typ T im Funktionskörper vergleichen, benötigen wir implicitzusätzlich zur ClassTagAnnotation einen orderer-Parameter .
AlvaPan
Ich fand diese Java-orientierte Frage auch hilfreich, um zu verstehen, warum wir keine ClassTags für zB Listen benötigen, aber Martins SIP deutete auch darauf hin: stackoverflow.com/questions/1817524/generic-arrays-in-java
bbarker