Kotlin et Immuable Collections?
Je suis à l'apprentissage de Kotlin et il est à la recherche probablement, je souhaiterez peut-être utiliser comme langue principale dans l'année à venir. Cependant, je continue à faire des recherches contradictoires que Kotlin ou n'ont pas immuable collections et je suis en train de voir si j'ai besoin d'utiliser Google Goyave.
Quelqu'un peut-il me donner de conseils à ce sujet? Ne sont, par défaut, utilisez Immuable collections? Ce que les opérateurs de retour mutable ou immuable collections? Si non, existe-il des plans pour les mettre en œuvre?
- Il y a une légère façon de protéger Kotlin collections comme immuable, plutôt que de seulement en lecture seule, voir: stackoverflow.com/a/38002121/3679676
Vous devez vous connecter pour publier un commentaire.
Kotlin de
List
de la bibliothèque standard est en lecture seule:Comme mentionné, il y a aussi le
MutableList
Pour cette raison, Kotlin applique readonly comportement, grâce à ses interfaces, au lieu de lancer des Exceptions de l'exécution comme Java par défaut des implémentations ne.
De même, il est un
MutableCollection
,MutableIterable
,MutableIterator
,MutableListIterator
,MutableMap
, etMutableSet
, voir la stdlib de la documentation.C'est confus, mais il y a trois, deux types de l'immuabilité:
MutableList
)List
), mais quelque chose peut-cast (à Mutables, ou de changer de Java)Ainsi dans le cas (2)
List
est juste une interface qui n'ont pas la mutation des méthodes, mais vous pouvez modifier l'instance si vous le lancez àMutableList
.Avec Goyave (cas (3)) vous êtes sûr de personne pour changer de la collection, même avec un plâtre ou d'un autre thread.
Kotlin choisi d'être en lecture seule pour utiliser Java collections directement, donc il n'y a pas de frais généraux ou de la conversion en utilisant Java collections..
List
est en lecture seule, pas immuable. Les autres appelants (Java par exemple) peut modifier la liste. Kotlin les appelants peuvent fonte de la liste et de les modifier. Il n'est pas immuable de protection.Que vous voyez dans d'autres réponses, Kotlin a readonly interfaces mutable collections qui vous permettent de visualiser une collection à travers une lecture seule lentille. Mais la collection ne peut être contournée par coulage ou manipulées à partir de Java. Mais en coopérative Kotlin code c'est bien, la plupart des utilisations n'ont pas besoin de vraiment immuable collections et si votre équipe évite les jette à la mutable forme de la collection, alors peut-être que vous n'avez pas besoin pleinement immuable collections.
La Kotlin collections permettent à la fois de copie sur le changement des mutations, ainsi que des paresseux, des mutations. Donc, pour répondre à une partie de vos questions, des choses comme
filter
,map
,flatmap
, les opérateurs+
-
tous de créer des copies lorsqu'il est utilisé contre les non paresseux collections. Lorsqu'il est utilisé sur unSequence
ils modifient les valeurs de la collection car il est accessible et de continuer à être paresseux (résultant dans un autreSequence
). Bien que, pour unSequence
, l'appel de n'importe quoi commetoList
,toSet
,toMap
sera le résultat final de la copie est faite. Par la convention de nommage de presque tout ce qui commence parto
est de faire une copie.En d'autres termes, la plupart des opérateurs vous retourner le même type que vous avez commencé avec, et si c'est de type "lecture seule", puis vous recevrez une copie. Si ce type est paresseux, alors vous aurez paresseusement appliquer la modification jusqu'à ce que vous demande la collection dans son intégralité.
Certaines personnes veulent eux pour d'autres raisons, telles que le traitement en parallèle. Dans ces cas, il pourrait être préférable de regarder vraiment haut de la performance des collections conçues pour ces fins. Et de les utiliser uniquement dans les cas, pas dans tous les cas généraux.
Dans la JVM monde, il est difficile d'éviter d'interopérabilité avec les bibliothèques qui veulent standard de Java collections, et de la conversion vers ou à partir de ces collections ajoute beaucoup de douleur et de frais généraux pour les bibliothèques qui ne prennent pas en charge les interfaces communes. Kotlin donne un bon mélange de l'interopérabilité et de l'absence de conversion, avec readonly protection par contrat.
Donc, si vous ne pouvez pas éviter de vouloir immuable collections, Kotlin fonctionne facilement avec quoi que ce soit à partir de la JVM de l'espace:
Aussi, le Kotlin équipe travaille sur Immuable Collections de mode natif pour Kotlin, cet effort peut être vu ici:
https://github.com/Kotlin/kotlinx.collections.immutable
Il ya beaucoup d'autres de la collection de cadres pour tous les différents besoins et contraintes, Google est votre ami pour les trouver. Il n'y a aucune raison pour que le Kotlin équipe doit se réinventer pour sa bibliothèque standard. Vous avez beaucoup d'options, et ils se spécialisent dans divers domaines tels que la performance, l'utilisation de la mémoire, pas de la boxe, l'immuabilité, etc. "Le choix est Bon" ... donc certains autres: HPCC, HPCC-RT, FastUtil, Koloboke, Trove et de plus...
Il y a même des efforts comme Pure4J qui, depuis Kotlin prend en charge les Annotations de traitement, peut-être que peut avoir un port de Kotlin pour les mêmes idéaux.
Kotlin 1.0 n'aura pas immuable des collections de la bibliothèque standard. Il ne, cependant, ont en lecture seule et mutable interfaces. Et rien ne vous empêche d'utiliser la troisième partie immuable de la collection de bibliothèques.
Méthodes de Kotlin de
List
interface "en charge uniquement un accès en lecture seule à la liste" bien que les méthodes de sonMutableList
charge de l'interface "ajout et suppression d'éléments". Deux de ceux-ci, cependant, ne sont interfaces.Kotlin de
List
interface applique un accès en lecture seule au moment de la compilation, au lieu de reporter ces vérifications à l'exécution comme lejava.util.Les Collections.unmodifiableList(java.util.Liste)
(qui "retourne un inmodifiable vue de la liste des... [où] les tentatives de modification de la liste retournée... résultat dans unUnsupportedOperationException
." Il ne fait pas valoir l'immuabilité.Envisager la suite de Kotlin code:
Avis comment
readOnlyList
est unList
et des méthodes telles queadd
ne peut pas être résolu (et ne compile pas),mutableList
peut naturellement être muté, etadd
surimmutableList
(à partir de Google Goyave) peut également être résolu au moment de la compilation, mais déclenche une exception au moment de l'exécution.Toutes les affirmations ci-dessus passent à l'exception de la dernière qui résultats dans
Exception in thread "main" java.lang.AssertionError: Expected <[1, 2, 3, 4]>, actual <[1, 2, 3]>.
c'est à dire Nous avons réussi à muté en lecture seuleList
!Notez que l'utilisation de
listOf(...)
au lieu dearrayListOf(...)
retours, effectivement, une liste immuable que vous ne pouvez pas le jeter à tout mutable type de liste. Cependant, l'utilisation de laList
interface pour une variable n'empêche pas unMutableList
d'être assigné (MutableList<E>
s'étendList<E>
).Enfin, notez qu'une interface Kotlin (comme en Java) ne peut pas appliquer l'immutabilité qu'il "ne peut pas stocker l'état" (voir Interfaces). En tant que tel, si vous voulez immuable collection vous avez besoin d'utiliser quelque chose comme ceux fournis par Google Goyave.
Voir aussi ImmutableCollectionsExplained · google/goyave Wiki · GitHub
REMARQUE: Cette réponse est ici, parce que le code est simple et open-source et vous pouvez utiliser cette idée pour faire de votre collection que vous créez immuable. Il n'est pas conçu comme une annonce de la bibliothèque.
Dans Klutter bibliothèque, sont de nouveaux Kotlin Immuable des wrappers qui utilisent Kotlin délégation pour l'envelopper d'un existant Kotlin interface de collecte avec une couche de protection sans aucun gain de performance. Il n'y a alors aucun moyen de lancer la collection, son itérateur, ou d'autres collections, il pourrait revenir dans quelque chose qui pourrait être modifié. Ils deviennent en effet Immuable.
Voici un exemple de code montrant comment simplement la technique est, par gros de délégation de l'interface de la classe réelle tout en substituant la mutation des méthodes et des sous-collections renvoyées sont enveloppés à la volée.
Avec helper extension de fonctions pour le rendre facile d'accès:
Vous pouvez voir l'idée et de l'extrapoler à créer les classes manquantes à partir de ce code qui reprend les modèles pour d'autres référencé types. Ou d'afficher le code complet ici:
Et avec des tests montrant quelques-uns des trucs que les modifications autorisées avant, mais plus maintenant, avec l'bloqué jette et des appels à l'aide de ces gestionnaires.