Je dois récupérer les objets de classe dérivée stockés dans une carte avec le nom de classe respectif comme clé.
Comme indiqué ci-dessous
class PreScoreCalculator(data:Seq[Int]) extends Caluclator
Le nom de clé donné doit être obtenu objet / instance respectif de la carte
val calcName = "PreScore" val opt = getCalculatorByOperationName(calcName) if(opt.isInstanceOf[PreScoreCalculator] ) /// this is coming as false calculationController.calculate(opt) // this is not being executed.
J'appelle comme ci-dessous
def getCalculatorByOperationName(operation:String) : Option[ Calculator] = { calculatorsLookUp.get(operation) }
Attendez-vous à: Exécuter calculController.calculate (opt)
Erreur: Ci-dessus si la condition est fausse, donc ne pas être exécutée.
Alors, comment gérer ce problème?
Comment gérer ci-dessous, à savoir les objets constructeur par défaut?
trait Caluclator class PreScoreCalculator(data:Seq[Int]) extends Caluclator class BenchMarkCalculator(data:Seq[Int]) extends Caluclator val calculatorsLookUp:Map[String, Calculator] = Map[String, Calculator]( "PreScore" -> new PreScoreCalculator, "BenchMark" -> new BenchMarkCalculator )
3 Réponses :
Le problème ici est sur
if(opt.map(_.isInstanceOf[PreScoreCalculator]).getOrElse(false)) calculationController.calculate(opt.get)
car il renverra Option [Calculatrice]
et non Calculatrice
. Maintenant, cela ressemblera à ceci ..
val opt = getCalculatorByOperationName(calcName)
J'espère que cela vous aidera.
merci, puis-je savoir pourquoi vous utilisez .map ici? si ce n'est pas le cas .isInstanceOf [PreScoreCalculator] renvoie false si la clé n'est pas "PreScore", non? pourquoi avons-nous besoin de .getOrElse (false) ???
D'accord. Premièrement, le résultat de opt
est toujours Option [Calculator]
et l'objet Predef de Scala offre une conversion implicite qui vous permet d'écrire key -> value comme syntaxe alternative pour la paire ( valeur clé). Dans le cas où le résultat est None, alors il ira à .getOrElse (false)
donc c'est sûr.
Vous avez un petit bug:
opt
est de type Option [Calculatrice]
Dans Scala, une bonne façon de gérer cela est correspondance de modèle:
opt.filter(_.isInstanceOf[PreScoreCalculator]) .foreach(calculationController.calculate)
Ou faites-le d'une manière plus déclarative:
opt match { case Some(calculator: PreScoreCalculator) => calculationController.calculate(calculator) case _ => // nothing to do }
Cependant l'utilisation de instanceOf
est un peu un anti-pattern.
Comme astuce:
Utilisez println (opt.getClass)
> puis vous voyez la classe .
merci pour la réponse rapide, désolé cette exécution tout le temps même si la clé n'est pas PreScore. Et println (opt.getClass) donne "class scala.Some"
vous avez raison désolé - j'ai corrigé ma réponse et testé maintenant les deux cas;)
merci beaucoup, pourquoi utilisez foreach ici? Que suis-je en train d'itérer ici?
opt
est de type Option [Calculatrice]
. Si vous voulez en faire quelque chose, vous devez le déballer, pour l'utiliser> foreach
le fait - vérifiez l'API de Option
.
Merci pour la clarté, si mon PreScoreCalculator prend un constructeur à savoir PreScoreCalculator (données: Seq [Int]) comment peut-il le gérer, dans le scénario ci-dessus?
si calculer
prend une calculatrice
, vous le gérez comme ci-dessus - sinon vous devez ajuster votre question et ajouter la fonction calculer
pour plus de clarté.
okey laissez-moi le dire d'une manière différente? comment mettre cette "classe PreScoreCalculator (données: Seq [Int]) étend Caluclator" dans la carte?
Vous ne devez pas appeler isInstanceOf
& asInstanceOf
manuellement, car cela jette essentiellement le compilateur.
Vous devriez utiliser la correspondance de modèle à la place:
opt match { case Some(c: PreScoreCalculator) => calculationController.calculate(c) ... // Other calculators. case None => println("Calculator not found.") }
Remarque: c'est fondamentalement le même Ichoran et j'ai déjà dit dans gitter, je laisse juste ceci ici pour l'enregistrement .
Miguel Mejia Suarez Merci beaucoup pour plus de clarté, si mon PreScoreCalculator prend un constructeur à savoir PreScoreCalculator (données: Seq [Int]) comment le gérer, dans le scénario ci-dessus?
@Miguel Mejia Suarez Pouvez-vous s'il vous plaît recommander un bon livre pour apprendre la conception d'applications scala et les meilleures pratiques?
@Shyam Pouvez-vous préciser cela s'il vous plaît? Avez-vous également besoin d'extraire cette Seq
? PS: Pouvez-vous modifier le code des calculatrices, ou celles-ci sont hors de votre contrôle?
@Shyam Techniquement parlant, SO n'est pas un endroit pour demander des recommandations de livres / cours ... mais, comme c'est un commentaire et non une question en soi, je suppose que ce n'est pas trop mal. Bien sûr, tout le monde pensera différemment, mais j'ai beaucoup aimé "Programming in Scala" (Book) & "Functional Programming in Scala" (Spécialisation Coursera) pour commencer. Et après un certain temps, (la plupart des gens recommandent un an d’expérience) commencer à en apprendre davantage sur la PF «Scala with Cats» est un excellent début.