2017-02-07 2 views
1

Hier ist mein Problem.Scala bietet Typinformationen in der Unterklasse generische Funktion

Ich habe eine abstrakte Klasse, die eine Methode mit Typparametern als Eingabe und Ausgabe definiert. Ich möchte, dass die Unterklassen die Typinformationen beim Unterklassen bereitstellen, aber ich möchte es so machen, dass ich die ganze Klasse nicht parametriere.

Einige Pseudo-Code von dem, was ich anstrebe.

abstract class A { 
    def foo[T](t: T): T 
} 

class B() extends A { 
    override foo[Int](t: Int): Int = t + 1 
} 

class C() extends A { 
    override foo[Double](t: Double): Double = t + 1.0 
} 

Wie gebe ich die Typinformationen für Unterklassen weiter? Ich schaute auf ähnliche Probleme. Sie adressieren das mit Selbstarten, Typklassen und abstrakten Typen.

Dank

Antwort

2

Wie Sie gesagt haben, kann eine abstrakte Art auf A dass lösen:

abstract class A { 
    type T 
    def foo(t: T): T 
} 

class B extends A { 
    override type T = Int 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A { 
    override type T = Double 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

Wenn ich versuche, mit der foo-Funktion von außen zu arbeiten und etwas wie 'foo (t)' zu übergeben, wobei t als 'T <: A' definiert ist, bekomme ich' type mismatch; erwartet t.T; actual T' – zaxme

+0

Was meinst du mit "von außen gehen"? Sie müssen den Typ beim Erstellen der Instanz von "B" und "C" definieren. –

+0

'Klasse D [T <: A] { def blah (t: T): T = { t.foo (t) } }' – zaxme

1

Was ist mit "Parametrieren" auf der abstrakten Klasse:

abstract class A[T] { 
    def foo(t: T): T 
} 

class B extends A[Int] { 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A[Double] { 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

Sorry aber wie gesagt - ich möchte meine Klasse später nicht mit einer Type-Ursache einiger Unterklassen parametrisieren. – zaxme

+0

Ah OK, das ist gut, ich habe das vermisst (aber ich sehe nicht, wie das "Subklassenprobleme" verursachen kann) –

1

Ihre A ist besonders vielversprechend, dass es mit beliebigT aufgerufen werden kann. Jeder Typ, der es erweitert, muss dieses Versprechen erfüllen.

val a: A = ... 
val x = a.foo("a") // calls foo[String] 
val y = a.foo(1) // calls foo[Int] 

ist perfekt guter Code. Aber wenn es ausgeführt wird, kann a tatsächlich ein B, C oder alles sein, was A erweitert. Das "Bereitstellen der Typinformationen beim Unterklassifizieren" ist also nicht wirklich sinnvoll: Es würde die Bedeutung des Subtyping (oder von Typparametern) komplett durchbrechen.

Verwandte Themen