Frage

  

class TestClass[T](val x: T) { def +(other: TestClass[T]) = x + other.x }

Diese Definition gibt mir den folgenden Compiler-Fehler:

Fehler: Typenkonflikt;
gefunden: T
erforderlich: String
def + (andere: Testclass [T]) = x + other.x

ist es nicht möglich, Int oder Doppel als Typ-Parameter und die Verwendung zusätzlich in Scala zu verwenden ??

War es hilfreich?

Lösung

Zuerst wird die Fehlermeldung ist irreführend. scalac versucht, eine Methode + auf Wert x zu finden. Diese existiert nicht auf Art T, die überhaupt jede Art sein könnte. Dies ist ein unbegrenzt Typ Parameter aufgerufen. So versucht sie zu und implizite Ansicht anwenden. Predef.any2stringadd passt die Rechnung.

Sie können diese implizite Konvertierung deaktivieren, und die reale Fehlermeldung angezeigt:

 ~/code/scratch: cat plus.scala 
import Predef.{any2stringadd => _, _}

class TestClass[T](val x: T) { 
  def +(other: TestClass[T]) = x + other.x 
}
 ~/code/scratch: scalac plus.scala 
plus.scala:4: error: value + is not a member of type parameter T
  def +(other: TestClass[T]) = x + other.x 
                               ^
one error found

In C ++ wird die Typprüfung durchgeführt, nachdem der Typparameter vorgesehen ist, bei jedem Anruf Ort. Also ist diese Art von Code funktionieren würde. In Scala muss die generische Methode seinen Typ in seiner Definition überprüft, basierend auf nur auf den Grenzen des abstrakten Typs.

Wie VonC vorgeschlagen, könnten Sie einen Kontext auf dem Typparameter T zu constrain gebunden zur Verfügung stellen möchten, wenn auf eine Art, die eine entsprechende Instanz der Numeric Eigenschaft hat.

class TestClass[T: Numeric](val x: T) { 
  def +(other: TestClass[T]): T = {
    val num = implicitly[Numeric[T]]
    import num._
    x + other.x
  }
}

Hier ist, wie das aussieht mit allen implicits explizit gemacht:

class TestClass[T]{
  implicit <paramaccessor> private[this] val evidence$1: Numeric[T] = _;
  def this(x: T)(implicit evidence$1: Numeric[T]): TestClass[T] = {
    TestClass.super.this();
    ()
  };
  def +(other: TestClass[T]): T = {
    val num: Numeric[T] = scala.Predef.implicitly[Numeric[T]](TestClass.this.evidence$1);
    import num._;
    num.mkNumericOps(TestClass.this.x).+(other.x)
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top