J'ai le suivant Scala code.
import scala.actors.Actor
object Alice extends Actor {
this.start
def act{
loop{
react {
case "Hello" => sender ! "Hi"
case i:Int => sender ! 0
}
}
}
}
object Test {
def test = {
(Alice !? (100, "Hello")) match {
case i:Some[Int] => println ("Int received "+i)
case s:Some[String] => println ("String received "+s)
case _ =>
}
(Alice !? (100, 1)) match {
case i:Some[Int] => println ("Int received "+i)
case s:Some[String] => println ("String received "+s)
case _ =>
}
}
}
Après avoir fait Test.test
, Je reçois la sortie:
scala> Test.test
Int received Some(Hi)
Int received Some(0)
Je m'attendais à la sortie
String received Some(Hi)
Int received Some(0)
Quelle est l'explication?
En deuxième question, je reçois unchecked
avertissements avec ce qui précède comme suit:
C:\scalac -unchecked a.scala
a.scala:17: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure
case i:Some[Int] => println ("Int received "+i)
^
a.scala:18: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure
case s:Some[String] => println ("String received "+s)
^
a.scala:22: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure
case i:Some[Int] => println ("Int received "+i)
^
a.scala:23: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure
case s:Some[String] => println ("String received "+s)
^
four warnings found
Comment puis-je éviter les avertissements?
EDIT: Merci pour les suggestions. L'idée de Daniel est belle mais ne semble pas fonctionner avec des types génériques, comme dans l'exemple ci-dessous
def test[T] = (Alice !? (100, "Hello")) match {
case Some(i: Int) => println ("Int received "+i)
case Some(t: T) => println ("T received ")
case _ =>
}
Ce qui suit erreur L'avertissement est rencontré: warning: abstract type T in type pattern T is unchecked since it is eliminated by erasure
Cela est dû à l'effacement de type. Le JVM ne connaît pas de paramètre de type, sauf sur les tableaux. À cause de cela, Scala code ne peut pas vérifier si un Option
est un Option[Int]
ou un Option[String]
- Cette information a été effacée.
Vous pourriez corriger votre code de cette façon, cependant:
object Test {
def test = {
(Alice !? (100, "Hello")) match {
case Some(i: Int) => println ("Int received "+i)
case Some(s: String) => println ("String received "+s)
case _ =>
}
(Alice !? (100, 1)) match {
case Some(i: Int) => println ("Int received "+i)
case Some(s: String) => println ("String received "+s)
case _ =>
}
}
}
De cette façon, vous ne testez pas ce que le type de Option
est, mais que le type de son contenu suppose - en supposant qu'il y a du contenu. A None
tombera à travers le cas par défaut.
Toute information sur les paramètres de type n'est disponible que lors de la compilation, pas au moment de l'exécution (celle-ci est appelée effacement de type). Cela signifie qu'à l'exécution, il n'y a pas de différence entre Option[String]
et Option[Int]
, donc tout motif correspondant sur le type Option[String]
, va également correspondre Option[Int]
Parce qu'à l'exécution des deux est juste Option
.
Comme ce n'est presque toujours pas ce que vous avez l'intention, vous obtenez un avertissement. Le seul moyen d'éviter l'avertissement n'est pas de vérifier le type générique de quelque chose à l'exécution (qui va bien parce que cela ne fonctionne pas comme si vous le souhaitez de toute façon).
Il n'y a aucun moyen de vérifier si un Option
est un Option[Int]
ou un Option[String]
au moment de l'exécution (autre que d'inspecter le contenu s'il s'agit d'un Some
).