2017-04-20 5 views
0

Hell Scala Experten - Ich brauche deine Hilfe. Ich versuche, einige generische Funktionen mit Typparametern zu schreiben, jedoch die Typparameter sind nicht auflösend. Selbst einfache eingebaute Typen wie String sind nicht auflösend. Ich bin mit scala 2.12.1 und Intellij 2017,1Scala-Typ Parameter nicht auflösend

ich den Code-Schnipsel angeschlossen haben unter

import java.lang.String 

trait hello_t 
{ 
    def hello_meth1:String 
    def hello_meth2[T]():T 
} 

class file_hello extends hello_t 
{ 
    // for example String here resolves to java.lang.String 
    val name:String = "test" 

    override def hello_meth1 = "hello from method 1" 

    //But type parameter "String" for hello_meth2 does not resolve - to java.lang.String 
    // And I get a compilation error see - below 
    override def hello_meth2[String] = "Hello from method 2" 

} 


object test extends App 
{ 
    val f1 = new file_hello 

    f1.hello_meth1 

    f1.hello_meth2 

} 

/* -- compilation error -- 
Error:(19, 39) type mismatch; 
found : java.lang.String("Hello from method 2") 
required: String 
override def hello_meth2[String] = "Hello from method 2"         ^
*/ 

Antwort

4

Die Definition eines Verfahrens mit einem Typ-Parameter, abstrakt (wie es der Fall in Ihrem trait ist) oder nicht , bedeutet, dass diese Methode für alle möglichen Typen definiert ist (es sei denn, Sie geben eine bestimmte Grenze für den Typ an, was hier nicht die Frage ist).

Das heißt, wenn Sie hello_meth2[T](): T implementieren, sollten Sie einen Wert vom Typ T für jeden Typ angeben, nicht nur für den Typ, den Sie auswählen.

Zum Beispiel kann das Verfahren map[U](f: T => U): List[U] in List[T] ist ein Verfahren, das ein List[U] schafft, unabhängig von der Art U ist, vorausgesetzt, dass Sie eine Funktion haben T Werte in U Werte zu transformieren.

In Ihrem Fall, wenn Sie versuchen, hello_meth2 in file_hello zu implementieren, können Sie den Typ-Parameter geben den Namen String (die T im trait genannt wird), aber es ist immer noch ein Typ-Parameter, die für jede hält Typ, und nicht nur java.lang.String.

Was Sie versuchen (wenn ich es richtig verstehe), kann auf andere Weise gelöst werden: Was Sie wollen, ist keine Methode mit einem Typparameter, sondern eine Eigenschaft mit einem Typparameter. In der Tat möchten Sie, dass Ihr Merkmal eine Methode hat, deren Rückgabetyp von der spezifischen Implementierung des Merkmals abhängt, daher sollte dieser Typ ein Parameter des Merkmals sein.

trait hello_t[T] { 
    def hello_meth1:String 
    def hello_meth2():T 
} 

class file_hello extends hello_t[String] { 
    override def hello_meth1 = "hello from method 1" 
    override def hello_meth2() = "Hello from method 2" 
} 

Oder, wenn Sie nicht über Parameter des Typs mögen, können Sie Typeigenschaften (was mehr ist objektorientiert):

trait hello_t { 
    type T 
    def hello_meth1:String 
    def hello_meth2():T 
} 

class file_hello extends hello_t { 
    type T = String 
    override def hello_meth1 = "hello from method 1" 
    override def hello_meth2() = "Hello from method 2" 
}