6
votes

Les filtres causent-ils un débordement de pile?

Si je comprends, méthode Filtrices code> de griffe code> crée un wrapper em> sur la carte d'origine. Donc, si j'exécute le code ci-dessous M code> sera une chaîne de wrappers de 10k et la carte d'origine.

var m = Map(1 -> "one", 2 -> "two")
for(1 <- 0 until 10000) {m = m.filterKeys(_%2 == 0)}


0 commentaires

3 Réponses :


2
votes

Je ne pouvais pas reproduire le débordement de la pile, mais voici ce qui se passe:

override def filterKeys(p: A => Boolean): Map[A, B] = new DefaultMap[A, B] {
  override def foreach[C](f: ((A, B)) => C): Unit = for (kv <- self) if (p(kv._1)) f(kv)
  def iterator = self.iterator.filter(kv => p(kv._1))
  override def contains(key: A) = self.contains(key) && p(key)
  def get(key: A) = if (!p(key)) None else self.get(key)
}


0 commentaires

1
votes

Votre boucle ne s'exécute que 1 fois, si je copie Verbatim. À cause de cela, vous ne créez qu'une seule wrapper, alors ce qui était destiné à être une chaîne de 10000 wrappers est juste une chaîne de 1. Cela pourrait être une faute de frappe, mais la boucle,

for(i <- 0 until 10000) {m = m.filterKeys(_%2 == 0)}


3 commentaires

Merci. J'ai corrigé la faute de frappe que vous avez remarquée et dirigez la boucle plus d'itérations. Maintenant, le débordement de la pile fait . Eh bien, les FilterKeys sont vraiment dangereux ...


@Michael: FilterKeys n'est dangereux que si vous envisagez de l'exécuter des milliers de fois sans quoi que ce soit entre les deux. Dans la plupart des cas, son comportement paresseux est réellement souhaitable.


Oui, cela souligne un potentiel de mauvaise programmation fonctionnelle. Dans ce cas, il est probablement une bonne idée de s'assurer que m est toujours sa propre collection, peut-être dans le sens de m = map () ++ m.filterkeys (_% 2 == 0)



2
votes

J'ai pu la causer de pile de débordement comme celui-ci (scala 2.9.1) xxx

Vous pouvez éviter la trace de la pile en forçant filtres réellement faire son travail à chaque étape: xxx


0 commentaires