62 votes

Des exemples concrets de l'utilisation de symboles dans Scala?

Scala a des symboles, des noms qui commencent par une apostrophe ' et qui sont une sorte de constantes de chaîne.

Je sais symboles de Ruby (où ils commencent par un signe deux-points). En Ruby, ils sont utilisés pour certaines méta-programmation des tâches, comme générer les accesseurs et mutateurs pour les variables de membre (par exemple, attr_reader :name pour générer un getter pour name).

Je n'ai pas vu beaucoup de l'utilisation de symboles en Scala code encore. Quelles sont les utilisations pratiques des symboles dans les Scala?

33voto

Matthias Benkard Points 11264

Faire des symboles de vraiment s'intégrer dans le Scala?

Dans le merveilleux pays de Lisp, le code est représenté par des listes imbriquées à la lettre les objets qui indiquent eux-mêmes (chaînes de caractères, nombres, et ainsi de suite), et les symboles, qui sont utilisés comme identificateurs pour des choses comme les classes, les fonctions et variables. Comme le code Lisp a une structure très simple, Lisp permet au programmeur de manipuler (à la fois au moment de la compilation et de l'exécution). Clairement, quand on fait cela, le programmeur va inévitablement rencontrer des symboles comme des objets de données.

Si les symboles sont (et doivent être) des objets en Lisp dans tous les cas, alors pourquoi ne pas les utiliser comme table de hachage touches ou les énumérations? C'est la façon habituelle de faire les choses, et qu'il conserve dans un langage simple, que vous n'avez pas à définir un spécial de type énumération.

Pour résumer, les symboles sont naturellement utilisés pour le code de la manipulation, de l'énumération, et la saisie des données. Mais Java gens ne les utilisent pas l'identité comme relation d'équivalence entre les clés de hachage par défaut (qui traditionnel Lisp), ils peuvent utiliser les chaînes de caractères comme leurs clés. Les types Enum sont définis séparément en Scala. Et enfin, le code de données n'est pas pris en charge par la langue.

Donc, non, mon impression est que les symboles n'appartiennent pas à la Scala de langue. Cela dit, je vais garder un œil sur les réponses à cette question. Ils font preuve d'une réelle utilisation des symboles dans Scala que je ne peux pas penser de la droite maintenant.

(Addendum: Selon le dialecte de Lisp, Lisp symboles peuvent également être l'espace de noms qualifiés, ce qui est, bien sûr, extrêmement utile lors de la manipulation de code, et une fonctionnalité que les chaînes n'ont pas.)

18voto

Det Points 141

Cherchant un peu partout sur le web, il semble que le sens des symboles (symboles littéraux) dans (une langue comme l') Scala en comparaison avec des Cordes est une question de sémantique, et donc éventuellement même compilateur de sensibilisation.

'Chaîne' est un type de données, consistant en une séquence de caractères. Vous pouvez utiliser les chaînes et les manipuler. Les chaînes peuvent être sémantiquement toutes les données de texte, à partir d'un nom de fichier à un message à imprimer sur l'écran, une ligne dans un fichier CSV, ou quoi que ce soit.

Pour le compilateur -et donc de l'IDE - les chaînes de caractères sont des valeurs d'un type de données Chaîne de caractères, comme les nombres (séquences de chiffres) sont les valeurs d'un type de données de dire: Integer . Il y a sur le niveau de programme pas de différence entre "foo" et "bar".

Otoh, que les Symboles sont des identifiants, c'est à dire du point de vue sémantique de l'identification d'un élément dans le programme. Dans cette affaire, ils sont comme les noms de classe, la méthode des noms ou des noms d'attribut. Mais alors qu'un nom de classe identifie la classe -à-dire l'ensemble des propriétés de la déclaration de la classe de la structure et de comportement et un nom de méthode qui identifie la méthode -c'est à dire les paramètres et les états- , un nom de symbole identifie le symbole -c'est à dire en soi, rien de plus .

Ainsi, le compilateur peut explicitement la distinction entre les symboles 'foo et bar, comme il l'a fait la distinction entre les classes de Foo et Bar. Dans le cadre du compilateur de la table des symboles, vous pouvez appliquer les mêmes mécanismes dans un IDE par exemple, pour rechercher l'utilisation de " foo (c'est à dire les références à ce symbole), qui, comme vous, recherche pour l'utilisation de la classe Foo.

En comparaison, la recherche d'une chaîne "toto" exigera des approches différentes, comme le texte complet de numérisation. Il suit la même sémantique que la recherche de toutes les occurrences de 4711 dans le code du programme.

Voilà comment je comprends bien, quelqu'un peut me corriger si je me trompe.

15voto

jqno Points 7831

Selon la Scala livre, les Symboles sont internés: "Si vous l'écrire deux fois le même symbole, les deux expressions se réfèrent à la même Symbol objet."

En revanche, Strings ne sont internés si elles semblent littéralement (au moins en Java, ils sont, pas tout à fait sûr de la Scala). Donc je suppose que si vous faites beaucoup de sérialisation d' Strings qui sont alors placés dans des collections, vous pouvez utiliser des symboles à la place et vous épargner un peu de mémoire.

Mais je suis d'accord avec skaffman, je ne suis pas totalement convaincu de leur utilisation.

(En Ruby, Symbols sont, à l'exception de la méta-programmation exemple que vous donnez, souvent utilisés comme clés dans Hashes. En Ruby, c'est utile parce que là, Strings ne sont jamais internés: chaque String alloue de la mémoire. En Scala, il pourrait être utile, comme je l'ai mentionné, si vous le combinez avec beaucoup de (dé)sérialisation de sorte que le Java Strings n'obtenez pas internés).

15voto

Daniel C. Sobral Points 159554

Je suppose que Scala ajouté, parce que les langages fonctionnels les utiliser.

Ils ont oublié, cependant, d'ajouter de la capacité de la référence à un identificateur, par un symbole, qui est une sorte de point central de leur existence. Il y a une fonctionnalité expérimentale en Scala 2.8 qui donne à certains. Je vais vous citer la partie pertinente de la documentation de l'API complète:


@experimental

object Invocation 
extends AnyRef

Le plus commode de la syntaxe pour les invocation. Exemple d'utilisation:

    class Obj { private def foo(x: Int, y: String): Long = x + y.length }

Vous pouvez l'appeler reflectively de deux façons:

    import scala.reflect.Invocation._
    (new Obj) o 'foo(5, "abc")                 // The 'o' method returns Any
    val x: Long = (new Obj) oo 'foo(5, "abc")  // The 'oo' method casts to expected type.

Si vous appelez de l' oo méthode et ne donnent pas le type inferencer assez d'aide, il sera très probablement en déduire Nothing, ce qui entraînera une ClassCastException.

Auteur Paul Phillips

5voto

Saem Points 2415

Je crois que les comparaisons entre les symboles est plus rapide. Si vous avez utilisé Erlang, des symboles sont utilisés d'une tonne en passant autour des messages et que vous voulez quelque chose de pas cher, et rapide, qui fonctionne bien sur la machine les frontières. Je ne sais pas dans quel état à distance acteurs sont en Scala, autant que je me souvienne, ils ont été plutôt douteuses, mais dans l'avenir, lorsque en place, des symboles qui pourraient bien être très utile dans beaucoup de la même manière qu'ils sont en Erlang. Aussi des classes de cas, certains des avantages ne sont pas apparente, puis de nouveau, les symboles sont encore moins cher.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X