2017-04-20 1 views
0

Experts Hell Scala - J'ai besoin de votre aide. J'essaye d'écrire quelques fonctions génériques avec des paramètres de type, cependant les paramètres de type ne résolvent pas. Même les types construits simples comme String sont ne résolvant pas. J'utilise 2.12.1 scala et Intellij 2017,1paramètres de type scala non résolus

Je joins l'extrait de code ci-dessous

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"         ^
*/ 

Répondre

4

La définition d'une méthode avec un paramètre de type, abstraite (comme cela est le cas dans votre trait) ou non , signifie que cette méthode est définie pour tous les types possibles (sauf si vous donnez une limite pour le type, ce qui n'est pas la question ici). Cela signifie que, lorsque vous implémentez hello_meth2[T](): T, vous devez donner une valeur de type T pour tout type, et pas seulement celui que vous décidez.

Par exemple, la méthode map[U](f: T => U): List[U] dans List[T] est une méthode qui crée un List[U], quel que soit le type U est, à condition que vous avez une fonction pour transformer les valeurs en TU valeurs.

Dans votre cas, quand vous essayez de mettre en œuvre hello_meth2 dans file_hello, vous donnez le paramètre de type (qui est appelé T dans le trait) le nom String, mais il est encore un paramètre de type, qui détient pour tout tapez, et pas seulement java.lang.String. Ce que vous essayez de faire (si je le comprends correctement) peut être résolu d'une autre manière: ce que vous voulez n'est pas une méthode avec un paramètre de type, mais un trait avec un paramètre de type. En effet, vous voulez que votre trait ait une méthode dont le type de retour dépend de l'implémentation spécifique du trait, ce type devrait donc être un paramètre du trait.

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" 
} 

Ou, si vous ne voulez pas les paramètres de type, vous pouvez avoir des propriétés de type (qui est plus orienté objet):

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" 
}