Scala中的有效标识符字符

Lui*_*hys 48 scala operators

我觉得很困惑的一件事是知道我可以在方法和变量名中使用哪些字符和组合.例如

val #^ = 1 // legal
val #  = 1 // illegal
val +  = 1 // legal
val &+ = 1 // legal
val &2 = 1 // illegal
val £2 = 1 // legal
val ¬  = 1 // legal
Run Code Online (Sandbox Code Playgroud)

据我了解,字母数字标识符运算符标识符之间存在区别.除非用下划线(混合标识符)分隔,否则您可以将一个匹配或另一个匹配但不能同时混合.

Scala中的编程 6.10节,

运算符标识符由一个或多个运算符字符组成.运算符字符是可打印的ASCII字符,例如+,:,?,〜或#.

更确切地说,运算符字符属于Unicode数学符号集(Sm)或其他符号(So),或者不是字母,数字,括号,方括号,花括号,单个或双精度的7位ASCII字符引号,或下划线,句号,分号,逗号或后退字符.

所以我们被排除在使用()[]{}'"_.;,和`之外

我抬起头,统一的数学符号的维基百科,但我发现没有包括的那些+,:,?等是否有一个明确的清单某处的运营商角色是什么?

此外,任何想法为什么Unicode数学运算符(而不是符号)不算作运算符?

huy*_*hjl 61

使用规范中的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”
Run Code Online (Sandbox Code Playgroud)

但也考虑到Lexical Syntax的最开始,它定义了:

Parentheses ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’.
Delimiter characters ‘‘’ | ‘’’ | ‘"’ | ‘.’ | ‘;’ | ‘,’
Run Code Online (Sandbox Code Playgroud)

这是我想出来的.通过消除范围\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 ans symbols
val abc???_!^©® = 1 // mixing unicode letters and symbols
Run Code Online (Sandbox Code Playgroud)

注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
Run Code Online (Sandbox Code Playgroud)

注3:

其他看起来像运算符的东西是保留字:_ : = => <- <: <% >: # @还有\u21D2⇒和\u2190

  • 谢谢.此外,正如规范所述,我们仅限于Unicode基本多语言平面字符,即2字节字符\ ufffd.因此,从"So","阴阳"运算符是合法的,但是不支持"烤甘薯"运算符(它被解释为\ u1f36 +'0'). (2认同)

Did*_*ont 10

语言规范.给出了第1章中的规则,词法语法(第3页):

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

这与您在Scala中编程编程的提取基本相同.+不是Unicode数学符号,但它绝对是上面未列出的ASCII可打印字符(不是字母,包括_或$,数字,paranthesis,分隔符).

在你的清单中:

  1. #是非法的,因为该字符不是操作符(#^是合法的),而是因为它是保留字(第4页),用于类型投影.
  2. &2是非法的,因为你混合了一个操作符和一个非操作符,即数字2
  3. £2是合法的,因为£不是运算符字符:它不是7位ASCII,而是8位扩展ASCII.它不是很好,$也不是一个(它被认为是一封信).