在Scala中有效的标识符字符

5 浏览
0 Comments

在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数学操作符(而不是符号)不算作操作符呢?

admin 更改状态以发布 2023年5月23日
0
0 Comments

语言规范 在第一章词法语法中给出了规则(第3页):

  1. 操作符字符。这些字符包括所有可打印的ASCII字符(\u0020-\u007F),它们不属于上述任何集合(包括数学符号(Sm)和其他符号(So))。

这与您在《Programming in Scala》中摘录的内容基本相同。+不是Unicode数学符号,但它绝对是ASCII可打印字符(不是字母,包括下划线或$,数字,括号,分隔符)。

在您的列表中:

  1. #不合法,不是因为这个字符不是操作符字符(#^是合法的),而是因为它是一个保留字(第4页),用于类型投影。
  2. &2不合法,因为您混合了一个操作符字符&和一个非操作符字符数字2。
  3. £2是合法的,因为£不是操作符字符:它不是7位ASCII,而是8位扩展ASCII。这不好,就像$一样(它被认为是一个字母)。
0
0 Comments

根据规范中的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... (鼓声):

! # % & * + - / : < = > ? @ \ ^ | ~
以及SmSo——除了括号和句号。

总之,这里有一些示例,其中包括所有情况,请留意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

0