2017-10-01 3 views
0

Je travaille actuellement sur un projet dans Scala et j'ai rencontré un petit problème.Objets de cas de requête de correspondance dans Scala

J'utilise actuellement une instruction de correspondance pour déterminer le type d'un objet de cas. Je vais à travers cela en disant:

abstract class Symbol 
case object program extends Symbol 
case object stmt_list extends Symbol 
case object stmt extends Symbol 
case object expr extends Symbol 
case object term_tail extends Symbol 
case object term extends Symbol 
case object factor_tail extends Symbol 
case object factor extends Symbol 
case object add_op extends Symbol 
case object mult_op extends Symbol 


def expected_symToIndex(expected_sym: Symbol): Int = expected_sym match { 

    case program => 0 
    case stmt_list => 1 
    case stmt => 2 
    case expr => 3 
    case term_tail => 4 
    case term => 5 
    case factor_tail => 6 
    case factor => 7 
    case add_op => 8 
    case mult_op => 9 

    } 

Dans Eclipse, cela me donne un avertissement disant que

« motifs après un motif variable ne peut égaler (SLS 8.1.1) Si vous destiné à faire correspondre le programme d'objet dans le paquet, vous devez utiliser des accents graves, comme: programme ⇒ cas »

sur la première ligne. Tout le reste est un code inaccessible.

Après avoir testé mon programme, cette méthode renvoie toujours 0 (car elle s'exécute toujours sur la première ligne d'objet de la méthode). J'ai cherché des méthodes de correspondance d'objets, mais je n'ai pas trouvé beaucoup de matériel similaire à ce qui se passe ici. Je suis confus parce que ces symboles ne sont pas des variables en eux-mêmes; Ce sont des types que je vérifie à l'intérieur de la déclaration de match. En outre, le "programme" environnant et d'autres valeurs testées avec des retours ne fonctionnent pas. Lorsque je tente quelque chose comme ceci pour tester le type:

case a: program => 0 

Le compilateur me dit que ne peut pas être trouvé le type « programme ».

Merci!

+0

Y a-t-il une raison pour laquelle vous utilisez une classe abstraite au lieu d'un trait scellé? – fuzzycuffs

+0

Une raison pour laquelle tous vos objets sont en minuscules? Quand j'ai fait tous ces cas en majuscules, le code compilé est très bien. – Tanjin

Répondre

1

Essayez de définir case class au lieu de case object. Ensuite, vous devriez être capable de les utiliser dans la recherche de motifs.

abstract class Symbol 

case class program() extends Symbol 

case class stmt_list() extends Symbol 

case class stmt() extends Symbol 

case class expr() extends Symbol 

case class term_tail() extends Symbol 

case class term() extends Symbol 

case class factor_tail() extends Symbol 

case class factor() extends Symbol 

case class add_op() extends Symbol 

case class mult_op() extends Symbol 


object Main { 

    def expected_symToIndex(expected_sym: Symbol): Int = expected_sym match { 

    case x: program => 0 
    case x: stmt_list => 1 
    case x: stmt => 2 
    case x: expr => 3 
    case x: term_tail => 4 
    case x: term => 5 
    case x: factor_tail => 6 
    case x: factor => 7 
    case x: add_op => 8 
    case x: mult_op => 9 
    case _ => -1 
    } 

    def main(args: Array[String]): Unit = { 

    println(expected_symToIndex(program())) //prints 0 
    println(expected_symToIndex(stmt_list())) //prints 1 

    } 
} 
+0

Avez-vous oublié parens? Parce que de cette façon, vous obtenez toujours du code inaccessible en raison du motif variable. –

+0

Oui, je n'ai pas essayé de compiler. Maintenant, j'ai mis à jour ma réponse. Cela fonctionne correctement. – fcat

1

Votre program, stmt, expr, etc. sont définis comme object s pas class es et donc ils sont des valeurs non types. Cela devrait expliquer pourquoi vous ne pouvez pas utiliser case a: program =>.

En outre, la correspondance/casse dans Scala ne fonctionne pas comment vous l'avez décrit. Si vous utilisez une variable dans un cas comme x match { case a => ... }, alors le programme ne vérifie pas si x est égal à a et ensuite exécute ... - non il va correspondre à toute valeur et l'assigner à la variable a, de sorte que vous pouvez utiliser un à l'intérieur du ... pour se référer à la valeur correspondante.

Comme vous l'avez décrit, ce n'est pas ce que vous voulez faire. Lorsque vous ne voulez pas faire correspondre une valeur et l'assigner, mais plutôt correspondre à une valeur spécifique d'une variable, vous pouvez marquer la variable en utilisant des guillemets (comme le message d'erreur a essayé de vous le dire), comme ceci x match { case `a` => ... }.

Vous pouvez également marquer les object s comme case object s, ce qui (entre autres choses) indique au compilateur que vous avez l'intention de les utiliser pour la correspondance.

Voir aussi https://alvinalexander.com/scala/scala-unreachable-code-due-to-variable-pattern-message

+1

Vous ne pouvez pas attribuer quoi que ce soit à un 'objet' normal. Vous obtenez l'erreur de compilation 'réaffectation à val'. OP peut utiliser 'case a: program.type =>' pour correspondre au type de l'objet, btw. –

+0

Droit! J'ai enlevé la mauvaise phrase sur l'immutabilité. – drcicero