2016-06-27 1 views
1

Je n'arrive pas à comprendre comment, dans l'exemple suivant, la fonction bar1 est compilée, mais pas bar2.Effectuer une correspondance de modèle sur une valeur générique avec le type correspondant au type de retour

trait Key[T] { 
} 

trait KeyString extends Key[String] 

class Foo { 
    def bar1[T](key: Key[T]): T = key match { 
     case k: KeyString => "hallo" 
     } 

    /*def bar2[T](key: T): T = key match { 
      case k: String => "hallo" 
      }*/ 
} 

code échantillon en ligne: http://www.tutorialspoint.com/compile_scala_online.php?PID=0Bw_CjBb95KQMZGtUOU9yYXpWcEE

Quelqu'un pourrait-il expliquer s'il vous plaît, pourquoi bar1 le compilateur peut comprendre, que « Hallo » est de type T et bar2 qui est impossible. J'ai cherché pendant un bon moment et je n'ai pas pu trouver d'explication.

Merci d'avance.

Répondre

0

La situation dans bar2 est plus complexe qu'il n'y paraît au premier abord. Par exemple. Imaginons qu'il y avait une sous-classe String appelée String1. Ensuite, si T est String1, key correspondrait case k: String, mais "hallo" aurait le mauvais type. Il n'y a pas un tel sous-type, car String arrive à être final, mais il serait également étrange si cela compilé ou non en fonction de la finalité de String. , Parce que ce modèle spécifique (qui est appelé GADT: type de données algébriques généralisées) a une prise en charge spéciale du compilateur. Ce support n'est pas parfait: voir par ex. https://gist.github.com/pchiusano/1369239.

+0

Merci pour votre excellente réponse. Juste une chose que je ne comprends pas: Pourquoi serait-ce étrange si elle compilait sur la base de la finalité de String (ou en général le type de résultat). Si le type de résultat est final et égal au type correspondant, il serait correct de déduire que T est égal à ce type, n'est-ce pas? – Cornelius

+1

Ok, j'ai trouvé la réponse moi-même: T peut toujours être le type singleton d'une instance, laquelle finalité ne l'exclut pas. Voir: https://issues.scala-lang.org/browse/SI-127 – Cornelius