55 votes

Caractères d'identification valides en Scala

Une chose que je trouve assez déroutante est de savoir quels caractères et quelles combinaisons je peux utiliser dans les noms de méthodes et de variables. Par exemple

val #^ = 1 // legal
val #  = 1 // illegal
val +  = 1 // legal
val &+ = 1 // legal
val &2 = 1 // illegal
val £2 = 1 // legal
val ¬  = 1 // legal

Si je comprends bien, il y a une distinction entre identifiants alphanumériques y identifiants d'opérateurs . Vous pouvez combiner l'un ou l'autre, mais pas les deux, à moins qu'ils ne soient séparés par un trait de soulignement (a). identifiant mixte ).

De Programmation en Scala section 6.10,

Un identifiant d'opérateur est constitué d'un ou plusieurs caractères d'opérateur. Les caractères d'opérateur sont des caractères ASCII imprimables tels que +, :, ?, ~ ou #.

Plus précisément, un caractère opérateur appartient à l'ensemble Unicode de symboles mathématiques (Sm) ou d'autres symboles (So), ou encore aux caractères ASCII à 7 bits qui sont utilisés dans la plupart des pays. ASCII qui ne sont pas des lettres, chiffres, parenthèses, crochets, accolades crochets, accolades, guillemets simples ou doubles, ou un trait de soulignement, un point, un point-virgule, une virgule ou un caractère de cochage arrière.

Il nous est donc interdit d'utiliser ()[]{}'"_.;, et `

J'ai cherché les symboles mathématiques Unicode sur Wikipedia mais ceux que j'ai trouvés n'incluaient pas + , : , ? etc. Existe-t-il une liste définitive quelque part de ce que sont les caractères des opérateurs ?

Par ailleurs, avez-vous une idée de la raison pour laquelle les opérateurs mathématiques Unicode (plutôt que les symboles) ne sont pas considérés comme des opérateurs ?

3 votes

² me manque particulièrement. Scala promet en quelque sorte que l'on peut faire du code qui utilise des noms de variables (et de méthodes) intelligents. Mais on ne peut pas donner une valeur à une variable x². Caractère illégal.

70voto

huynhjl Points 26045

Travailler à partir de la syntaxe EBNF de la spécification :

upper ::= ‘A’ | ... | ‘Z’ | ‘$’ | ‘_’ and Unicode category Lu
lower ::= ‘a’ | ... | ‘z’ and Unicode category Ll
letter ::= upper | lower and Unicode categories Lo, Lt, Nl
digit ::= ‘0’ | ... | ‘9’
opchar ::= “all other characters in \u0020-007F and Unicode
            categories Sm, So except parentheses ([]) and periods”

Mais aussi en tenant compte du tout début sur la syntaxe lexicale qui définit :

Parentheses ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’.
Delimiter characters ‘‘’ | ‘’’ | ‘"’ | ‘.’ | ‘;’ | ‘,’

Voici ce que j'ai trouvé. En travaillant par élimination dans l'intervalle \u0020-007F en éliminant les lettres, les chiffres, les parenthèses et les délimiteurs, nous avons pour opchar ... (roulement de tambour) :

*`! # % & + - / : < = > ? @ \ ^ | ~** et aussi [Sm](http://www.fileformat.info/info/unicode/category/Sm/list.htm) y [So`](http://www.fileformat.info/info/unicode/category/So/list.htm) - sauf pour les parenthèses et les points.

(Edit : ajout d'exemples valables ici :). En résumé, voici quelques exemples valables qui mettent en évidence tous les cas - faites attention à \ dans le REPL, j'ai dû l'échapper en tant que \\ :

val !#%&*+-/:<=>?@\^|~ = 1 // all simple opchars
val simpleName = 1 
val withDigitsAndUnderscores_ab_12_ab12 = 1 
val wordEndingInOpChars_!#%&*+-/:<=>?@\^|~ = 1
val !^©® = 1 // opchars ans symbols
val abcαβγ_!^©® = 1 // mixing unicode letters and symbols

Note 1 :

J'ai trouvé cet Unicode index des catégories pour comprendre Lu, Ll, Lo, Lt, Nl :

  • Lu (lettres majuscules)
  • Ll (lettres minuscules)
  • Lo (autres lettres)
  • Lt (titre)
  • Nl (lettres et chiffres comme les chiffres romains)
  • Sm (symbole mathématique)
  • Alors (symbole autre)

Note 2 :

val #^ = 1 // legal   - two opchars
val #  = 1 // illegal - reserved word like class or => or @
val +  = 1 // legal   - opchar
val &+ = 1 // legal   - two opchars
val &2 = 1 // illegal - opchar and letter do not mix arbitrarily
val £2 = 1 // working - £ is part of Sc (Symbol currency) - undefined by spec
val ¬  = 1 // legal   - part of Sm

Note 3 :

D'autres choses qui ressemblent à des opérateurs et qui sont des mots réservés : _ : = => <- <: <% >: # @ et aussi \u21D2 ⇒ et \u2190

2 votes

Merci. De plus, comme le dit la spécification, nous sommes limités aux caractères Unicode Basic Multilingual Plane, c'est-à-dire des caractères de 2 octets au maximum. \ufffd. Ainsi, de So , \u262f l'opérateur Yin Yang est légal, mais \u1f360 l'opérateur Patate Douce Rôtie n'est pas supporté (il est interprété comme \u1f36 + '0').

1 votes

Dans Scala 2.9, £ est maintenant signalé comme un illegal character (vraisemblablement le comportement correct par rapport à la spécification).

0 votes

Le caractère § n'est pas non plus valide. Une idée de la raison ?

10voto

Didier Dupont Points 18256

La spécification du langage . donne la règle dans le chapitre 1, syntaxe lexicale (à la page 3) :

  1. Caractères de l'opérateur. Il s'agit de tous les caractères ASCII imprimables imprimables \u0020 - \u007F. qui ne sont dans aucun des ensembles ci-dessus, les sym- boles mathématiques (Sm) et les autres symboles (So).

C'est essentiellement la même chose que votre extrait de Programmation en Scala. + n'est pas un symbole mathématique Unicode, mais c'est définitivement un symbole Caractère imprimable ASCII ne figurant pas dans la liste ci-dessus (pas une lettre, y compris _ ou $, un chiffre, une paranthèse, un délimiteur).

Dans votre liste :

  1. # est illégal non pas parce que le caractère n'est pas un caractère opérateur (#^ est légal), mais parce que c'est un mot réservé (à la page 4), pour la projection de type.
  2. &2 est illégal car vous mélangez un caractère opérateur & et un caractère non opérateur, le chiffre 2.
  3. Le £2 est légal parce que le £ n'est pas un caractère opérateur : ce n'est pas un ASCII à sept bits, mais un ASCII étendu à huit bits. Ce n'est pas agréable, car $ n'en est pas un non plus (il est considéré comme une lettre).

0 votes

Les "sym- boles mathématiques (Sm) et autres symboles (So)" sont l'objet de "consistent en" ou "en aucun" ?

0voto

Hartmut Points 426

Utiliser des backticks pour échapper aux limitations et utiliser des symboles Unicode

val `r→f` = 150
println(`r→f`)

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