Действительный идентификатор символов в Scala
Одна вещь, которую я нахожу довольно запутанной, это знание, какие символы и комбинации я могу использовать в именах методов и переменных. Например
val #^ = 1 // legal
val # = 1 // illegal
val + = 1 // legal
val &+ = 1 // legal
val &2 = 1 // illegal
val £2 = 1 // legal
val ¬ = 1 // legal
Насколько я понимаю, существует различие между буквенно-цифровыми идентификаторами и идентификаторами операторов. Вы можете смешивать одно или другое совпадение, но не оба одновременно, если они не разделены подчеркиванием (смешанный идентификатор).
Из раздела Программирование в Scala 6.10,
Идентификатор оператора состоит из одного или нескольких символов оператора. Символы оператора являются печатными символами ASCII, такими как +,:,?, ~ Или #.
Точнее, символ оператора принадлежит к набору математических символов Unicode (Sm) или других символов (So) или 7-разрядным символам ASCII, которые не являются буквами, цифрами, круглыми скобками, квадратными скобками, фигурными скобками, одинарными или двойными кавычка или символ подчеркивания, точка, точка с запятой, запятая или обратный тик.
Таким образом, мы исключены из использования ()[]{}'"_.;,
и `
Я посмотрел математические символы Unicode в Википедии, но те, которые я нашел, не включали +
, :
, ?
и т.д. Есть ли где-нибудь определенный список символов оператора?
Кроме того, есть идеи, почему математические операторы Unicode (а не символы) не считаются операторами?
3 ответа
Работа от синтаксиса EBNF в спецификации:
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”
Но также с учетом самого начала лексического синтаксиса, который определяет:
Parentheses ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’.
Delimiter characters ‘‘’ | ‘’’ | ‘"’ | ‘.’ | ‘;’ | ‘,’
Вот что я придумаю. Работая отбором в ассортименте \u0020-007F
, исключая буквы, цифры, скобки и разделители, мы имеем для opchar
... (барабанная дробь):
! # % & * + - / : < = > ? @ \ ^ | ~
а также Sm
а также So
- за исключением скобок и периодов.
(Изменить: добавив действительные примеры здесь:). Таким образом, вот несколько действительных примеров, которые выделяют все случаи - следите за \
в REPL я должен был сбежать как \\
:
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
Примечание 1:
Я нашел этот индекс категории Unicode, чтобы выяснить, Lu, Ll, Lo, Lt, Nl
:
- Лу (заглавные буквы)
- Ll (строчные буквы)
- Ло (другие буквы)
- Lt (заглавие)
- Nl (буквенные числа, такие как римские цифры)
- Sm (символ математики)
- Итак (символ другой)
Заметка 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
Заметка 3:
Другие операторские вещи, которые являются зарезервированными словами: _ : = => <- <: <% >: # @
а также \u21D2
⇒ и \u2190
←
Спецификация языка. дает правило в главе 1, лексический синтаксис (на странице 3):
- Оператор персонажей. Они состоят из всех печатаемых символов ASCII. которые не входят ни в один из перечисленных выше наборов, математические символы (Sm) и другие символы (So).
Это в основном то же самое, что и ваша выдержка из "Программирование в программировании в Scala" +
не является математическим символом Unicode, но это определенно печатный символ ASCII, не перечисленный выше (не буква, включая _ или $, цифра, парантез, разделитель).
В вашем списке:
- # недопустимо не потому, что символ не является символом оператора (#^ допустимо), а потому что это зарезервированное слово (на странице 4) для проекции типа.
- & 2 недопустимо, потому что вы смешиваете символ оператора & и неоператорский символ, цифра 2
- £ 2 допустимо, потому что £ не является символом оператора: это не семибитовый ASCII, а расширенный 8-битный ASCII. Это не приятно, как
$
тоже не один (это считается буквой).
используйте обратные кавычки, чтобы избежать ограничений и использовать символы Unicode
val `r→f` = 150
println(`r→f`)