10
votes

SCALA 2.10 Typetag Usage

Je creuse une nouvelle API de réflexion Scala et je ne peux pas comprendre pourquoi l'extrait de suivi ne fonctionne pas comme prévu. Compte tenu de la hiérarchie (essayé de simplifier autant que je peux):

trait MF[A] {
  implicit def m: Manifest[A]

  def f[T <: A: Manifest]: PartialFunction[Any, A] = {
    case msg: T if typeOf[T] =:= typeOf[A] => msg
  }
}

class MFilter[T: Manifest] extends MF[T] {
  def m = manifest[T]
}


2 commentaires

Il peut être utile d'ajouter l'avertissement que vous obtenez pour casse: t dans votre code: AVERTISSEMENT: le type de résumé T dans type motif T est décoché car il est éliminé par effacement . Je ne vois pas cet avertissement avec l'ancienne approche manifeste .


@ Som-Snytt, pense, c'est creuser dans . Manque de pratique anglaise. Je vais essayer d'être plus prudent la prochaine fois :)


4 Réponses :


2
votes

En réalité, vous ne vérifiez pas le type de msg ici, Compiler vous avertira que MSG: T est effacé. Tout ce que vous avez laissé la vérification est que le type défini sur Tfilter est identique à un type défini sur la fonction f. Je ressemble à la correspondance de modèle est "assisté" par Manifeste et Classtag, alors msg: T est en effet un type correct. Si vous l'essayez avec des primitives ou une liste [t], cela ne fonctionnera pas correctement. P>

val mFilter = new MFilter[Int]
messages collect mFilter.f[Int] // res31: Seq[Int] = List()

val messages = List(List(1), List("a"))
val mFilter = new MFilter[List[Int]]
messages collect mFilter.f[List[Int]] // res32: List[List[Int]] = List(List(1), List(a))


0 commentaires

6
votes

Je pense donc que le problème clé ici est que vous devez faire correspondre au type de msg , mais son type de compilation est n'importe quel (à partir du Partialfunction Déclaration). Essentiellement, vous voulez un typé de pour chaque élément de votre liste [n'importe quel] . Mais puisqu'ils ont tous un type de temps compilé de tout en vertu de tous étant mis dans la même liste, vous n'allez pas obtenir un typetag est plus spécifique que que.

Je pense que ce que vous voulez probablement faire est d'utiliser classtag au lieu de Typetag : xxx

comme Ajran pointe , tout comme la version manifeste , vous devrez être au courant de tous Les limitations des types d'exécution, y compris des problèmes d'effacement et de boxe: xxx

Il existe certaines suggestions sur la manière de faire Typetag plus utile pour la correspondance des motifs (par exemple, < un href = "https://issues.scala-lang.org/browse/si-6517" rel = "NOfollow NOREFERRER"> SI-6517 ), mais je pense que ceux qui n'auront qu'ajouter quand vous correspondez contre un objet avec un type , pas un objet avec type de compilation de tout .


4 commentaires

Mais en raison de Scaladoc , Classtag est un cas particulier plus faible de Typetag , alors je suppose que ce dernier devrait fonctionner aussi.


Si vous regardez un lien dans ma réponse, vous verrez que ce n'est pas le cas: «Nous avons définitivement discuté d'utiliser des balises de type pour aider à assortir le modèle, mais je pense, Adriaan a des choses plus importantes à faire en ce moment.»


Droite, les docs disent " Les classtags sont un cas spécial plus faible de scala.reflect.api.typetags # Typetags, en ce sens qu'elles n'envoient que la classe d'exécution d'un type donné, tandis qu'une typage contient toutes les informations de type statique ". Mais si votre type statique est tout , un typetag ne vous aidera pas de toute façon, et le meilleur que vous puissiez faire est la classe d'exécution du classtag .


@Arjan, Steve, Som-Snytt, merci pour votre aide. Pense maintenant, je comprends comment ça marche. Toutes les réponses fournissent des informations utiles, mais je devrais en choisir un.



0
votes

Merci à tous de commenter. Pensez, j'ai trouvé la raison pour laquelle classtag doit être utilisé dans la correspondance des motifs.

J'ai réussi à trouver [SI-5143] correspondant à la correspondance des types abstraits ne " t travail , et il est associé commettras explique qu'il devrait y avoir une instance de CLASSTAG Pour faire un motif vérifiant.

Alors, oui, j'ai utilisé Typetag mal; En cas de correspondance de modèle, je devrais utiliser classtag .


1 commentaires

Voir ma réponse mise à jour - Je pense que le vrai problème est que msg a un type de compilation de n'importe quel . Ce n'est pas un type abstrait, c'est un type concret. C'est juste un type de béton inutile. ;-)



2
votes

juste pour le plaisir: xxx


0 commentaires