在Scala中有效的标识符字符
在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字符,例如+,:,?,~或#。
更准确地说,操作符字符属于数学符号(Sm)或其他符号(So)的Unicode集,或者属于7位ASCII字符中不是字母、数字、圆括号、方括号、花括号、单引号或双引号、下划线、句号、分号、逗号或反引号字符。
所以,我们不能使用()[]{}\'\"_.;,
和`
我在维基百科上查找了Unicode数学符号,但我找到的符号中并没有包括+
,:
,?
等。有没有一个明确的列表,说明哪些操作符字符是可以使用的呢?
另外,为什么Unicode数学操作符(而不是符号)不算作操作符呢?
语言规范 在第一章词法语法中给出了规则(第3页):
- 操作符字符。这些字符包括所有可打印的ASCII字符(\u0020-\u007F),它们不属于上述任何集合(包括数学符号(Sm)和其他符号(So))。
这与您在《Programming in Scala》中摘录的内容基本相同。+
不是Unicode数学符号,但它绝对是ASCII可打印字符(不是字母,包括下划线或$,数字,括号,分隔符)。
在您的列表中:
- #不合法,不是因为这个字符不是操作符字符(#^是合法的),而是因为它是一个保留字(第4页),用于类型投影。
- &2不合法,因为您混合了一个操作符字符&和一个非操作符字符数字2。
- £2是合法的,因为£不是操作符字符:它不是7位ASCII,而是8位扩展ASCII。这不好,就像
$
一样(它被认为是一个字母)。
根据规范中的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 and symbols val abcαβγ_!^ = 1 // Mixing Unicode letters and symbols
注意1:
我发现这个Unicode类别索引,以了解Lu、Ll、Lo、Lt、Nl
:
- Lu(大写字母)
- Ll(小写字母)
- Lo(其他字母)
- Lt(标题大小写)
- Nl(字母数字,如罗马数字)
- Sm(符号数学)
- So(符号其他)
注意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
←