2017-09-29 1 views
4

J'ai un extracteur qui extrait un objet d'une chaîne. Si j'essaie d'utiliser cet extracteur dans une correspondance de modèle, alors tout fonctionne comme prévu.Quelle est la différence de la fonction non appliquée dans la correspondance de modèle et dans une fonction partielle?

"" match { 
    case ItemStructure(item) => 
} 

Il fonctionne également dans une fonction de recherche de motif anonyme.

Option("").map { 
    case ItemStructure(item) => 
} 

Maintenant, si je tente d'utiliser cet extracteur dans une fonction partielle, le compilateur échoue avec le message: ne peut pas résoudre surchargées unapply

val func: PartialFunction[Any, Unit] = { 
    case ItemStructure(item) => 
} 

Si je renomme l'objet compagnon où la fonction unapply est situé alors tout fonctionne comme prévu.

Est-ce que quelqu'un pourrait expliquer pourquoi l'extrait ne fonctionne pas s'il se trouve dans l'objet compagnon?

Répondre

4

Il existe deux méthodes ItemStructure.unapply: celle créée par la classe case et celle que vous avez créée vous-même. Le premier prend un argument de type ItemStructure et le dernier prend un argument de type String.

Dans vos deux premiers exemples, le type de l'objet correspondant est String. Par conséquent, seule la seconde méthode unapply peut être appliquée et il n'y a aucune ambiguïté. Mais dans le dernier exemple, les deux méthodes unapply seraient admissibles, donc Scala ne sait pas lequel utiliser. Si vous placez votre méthode unapply ailleurs que dans l'objet compagnon, il n'y a plus deux méthodes unapply - seulement la vôtre (car l'autre réside toujours dans l'objet compagnon). Donc, cela résout l'ambiguïté: ItemStructure.unapply se réfère clairement à l'auto-généré unapply et NewName.unapply se réfère clairement à votre.

+0

Je ne pouvais pas comprendre comment le dernier exemple correspond aux deux méthodes non appliquées. Pouvez-vous également l'expliquer? – fcat

+0

@fcat Si le type est String, 'unapply (ItemStructure)' ne peut jamais correspondre, il n'est donc pas nécessaire de le prendre en compte. Si le type est 'ItemStructure',' unapply (String) 'ne peut jamais correspondre. Si le type est 'Any', les deux peuvent correspondre car un' Any' pourrait être un 'ItemStructure' ou il pourrait être un' String'. – sepp2k

+0

Ok, je suis aveugle pour voir que le dernier type est 'Any'. Merci pour l'explication! – fcat

2

Avec Any comme type de résultat Le compilateur ne parvient pas à savoir d'où il doit retirer la fonction de non-application. Votre unappl y définit uniquement le comportement pour le type String.

Cela fonctionnerait bien:

val func: PartialFunction[String, Unit] = { 
    case ItemStructure(item) => 
} 

Sinon, essayez de définir la fonction unapply qui prend le type Any.

+0

J'ai accepté la réponse de @ sepp2k car elle est plus détaillée. – akkie