9
votes

variables mutables vs collection Mutable

Dans ma demande, je dois pouvoir à des éléments d'échange dans la collecte. J'ai donc le choix:

  1. utiliser la collection mutable déclarée comme val
  2. ou utiliser la collection immuable déclarée comme var (et toujours Réattribuer nouvelle collection var )

    Mais Scala (dans la programmation fonctionnelle) mutabilité toujours évité. Alors, quelle est moins pire: la collecte mutable déclarée en utilisant val ou d'une collection immuable déclarée comme var


3 commentaires

Sans plus de contexte, il ne fait pas vraiment une différence. Ni est une approche fonctionnelle. collection Mutable probablement de meilleures performances que d'un immuable var.


@dbyrne collection Mutable effectuerez probablement mieux qu'un immuable var Whoa? ne sont pas ces deux jouer dans la même équipe? par exemple. val = misterMutableCollection collection.mutable ....


@ Om-nom-nom avec une var immuable, vous devrez construire une toute nouvelle collection et échanger. Avec un mutable val, vous pouvez utiliser les méthodes de collecte et d'appeler d'origine pour muter.


6 Réponses :


1
votes

mutabilité est la bête que vous feriez mieux de garder dans une cage. Idéalement, bien testé et le type de cage très utilisé comme scala collection est mutable.


0 commentaires

0
votes

réaffectations à var peut être difficile à lire / maintenir, surtout si cela se produit à plusieurs endroits dans une méthode, par exemple.

avec un val , vous obtenez au moins une immuable référence .

D'une manière générale la portée d'une collection mutable doit être aussi faible que possible. Donc, après avoir rempli la collection mutable complètement (en cas d'un tampon de courte durée), vous pouvez transformer en un un immuable, par exemple pour retourner ce que le résultat d'une méthode.

Comme dbyrne a souligné correctement: S'il est impossible de convertir la collection mutable en une un immuable (si vous implémentez un cache par exemple), et la collection mutable fait partie de l'API publique, puis un var peut-être mieux. Une autre option dans ce cas est de créer une copie immuable dans la méthode qui met en œuvre l'API publique.


1 commentaires

Ceci est la meilleure réponse à ce jour, à mon avis, mais il y a des cas où il est plus important pour la collection elle-même d'être immuable, et la référence est pas si important. Si vous êtes un auteur bibliothèque et vous voulez vous assurer que toute personne utilisant votre API ne mute pas une collection après votre retour à eux, un var immuable serait approprié.



4
votes

Si vous utilisez un var conservation d'une collection immuable vous pouvez le publier assez librement (bien que vous pouvez marquer le var comme @volatile ). A un moment donné tout autre code peut seulement obtenir un aperçu particulier de cet état qui ne peut jamais changer.

Si vous utilisez un val tenant une instance de collection mutable, vous devez conservez précieusement, car il peut être vu dans les états incohérents tout en étant mis à jour.


2 commentaires

Pouvez-vous s'il vous plaît un peu plus d'informations sur la façon dont fonctionne @volatile à Scala? D'après ce que je comprends des drapeaux que plusieurs threads peuvent y accéder en même temps, mais je ne suis pas sûr de ce que cette annotation change vraiment ou est-ce à la variable? Merci


@volatile fonctionne exactement le même que le mot-clé volatile en java fait. Il fonctionne sur le niveau VM. Voir stackoverflow.com/questions/2694439/... par exemple.



10
votes

Cela dépend vraiment de savoir si vous avez besoin de partager cette collection à grande échelle. L'avantage d'une collection mutable est qu'il est généralement plus rapide que la collection immuable, et il est plus facile d'avoir un seul objet à passer autour plutôt que d'avoir à vous assurer que vous pouvez définir un var de contextes différents. Mais comme ils peuvent changer de sous vous, vous devez être prudent, même dans un contexte mono-thread:

a.map(_ * 2)    // Map doesn't update, it produces a new copy!


0 commentaires

1
votes

Une méthode sûre que je l'ai utilisé fonctionne quelque chose comme ça .. d'abord cacher votre var pour le rendre thread-safe comme ceci:

def myListSafe = myList.toList (or some other safe conversion function like toMap, etc)


0 commentaires

0
votes

D'accord avec Rex, la plus grande préoccupation est de savoir si vous partagez la collection. Dans cette immuable utilisation de cas. Une autre alternative:

@volatile
private var myList = immutable.List.empty[Foo]
def theList = myList


0 commentaires