为什么标识符不能以数字开头?

为什么在java中(我不知道任何其他编程语言)标识符不能以数字开头,为什么以下声明也不允许?

int :b; int -d; int e#; int .f; int 7g; 

一般来说,你将这种限制放在一起有两个原因:

  1. 以电子方式解析是一件痛苦的事。
  2. 解析人类是一件痛苦的事。

请考虑以下代码段:

 int d, -d; d = 3; -d = 2; d = -d; 

如果-d是合法的标识符,那么最后会得到哪个值? -3还是2? 这是模棱两可的。

还要考虑:

 int 2e10f, f; 2e10f = 20; f = 2e10f; 

f最终有什么价值? 这也是模棱两可的。

另外,无论如何阅读都是一种痛苦。 如果有人声明2ex10 ,这是200万错字或变量名吗?

确保标识符以字母开头意味着它们可以与之冲突的唯一语言项是保留关键字。

那是因为Java语言规范的第3.8节说明了这一点。

标识符是Java字母和Java数字的无限长度序列,其中第一个必须是Java字母。 标识符不能与关键字(§3.9),布尔文字(§3.10.3)或空文字(§3.10.7)具有相同的拼写(Unicode字符序列)。

至于为什么做出这个决定 :可能是因为这简化了解析,避免了模糊的语法,允许在语言的更高版本中引入特殊语法和/或出于历史原因(即因为大多数其他语言具有相同的限制类似限制)。 请注意,带-d的示例示例特别清楚:

 int -d = 7; System.out.println("Some number: " + (8 + -d)); 

减号是标识符的第一部分,还是一元减号?

此外,如果你同时将-dd作为变量,那将完全不明确:

 int -d = 7; int d = 2; System.out.println("Some number: " + (8 + -d)); 

结果是15还是6?

我不完全确切,但我认为这是因为数字用于表示文字值,因此当编译器找到以数字开头的标记时,它知道它正在处理文字。 如果标识符可以以数字开头,则编译器需要使用预先查找标记中的下一个字符以查明它是标识符还是文字。

几乎任何语言都不允许这样的事情(我现在想不到一个),主要是为了防止混淆。

你的例子-d就是一个很好的例子。 编译器如何知道你的意思是“名为-d的变量”还是“变量d中数字的负数”? 由于它无法分辨(或者更糟糕的是,它可能因此无法确定在不读取文件的其余部分时键入的内容会发生什么),因此不允许这样做。

示例7g是一回事。 您可以通过在末尾添加字母来将数字指定为特定的基数或类型。 数字8357是Java中的int,其中8357L是一个long(因为末尾有一个’L’)。 如果变量可以从数字开始,那么可能会出现无法判断它是变量名还是文字的情况。

我会假设你列出的其他人有类似的原因,其中一些可能是历史性的(即C因为X而无法做到,而Java的设计看起来像C,所以他们遵守规则)。

在实践中,它们几乎从来都不是问题。 你很难找到令人烦恼的情况。 你最常遇到的是以数字开头的变量,但你总是可以拼出它们(即oneThing,twoThing,threeThing等)。

语言可以允许其中的一些内容,但这种简化的假设使编译器编写器和程序员更容易阅读程序。

解析器(通常)编写为首先将源文本分解为“标记”。 以数字开头的标识符看起来像数字。 除了5e3,在某些语言中是有效数字(5000.0)。

同时:和。 被标记为运算符。 在某些情况下,以其中一个开头的标识符会导致模糊的代码。 等等。

每种语言都需要定义什么是标识符的有效字符,什么不是。 部分考虑将是易于解析,部分将是避免歧义(换句话说,即使是完美的解析算法也不能一直确定),部分将是语言设计的偏好(在Java的情况下与C,C ++相似),有些只是随意的。

重点是它必须是某种东西,所以这就是它。

例如,我们是否希望拥有具有这些名称的对象?

 2ndInning 3rdBase 4thDim 7thDay 

但想象一下有人可能会尝试使用名称为666的变量:

 int 666 = 777; float 666F = 777F; char 0xFF = 0xFF; int a = 666; // is it 666 the variable or the literal value? float b = 666F // is it 666F the variable or the literal value? 

也许,我们可能会想到的一种方式是,以数字开头的变量必须以字母结尾 – 只要它不以0x开头并以用作hex数字的字母结尾,或者它不以诸如hex数字之类的字符结尾L或F等等

但是这样的规则会让Yogi Berra讽刺的程序员真的很难 – 你怎么能同时思考和打击呢? 您正在尝试尽可能快地编写计算机程序并且没有错误,然后您将不得不为所有这些小部分规则而烦恼。 作为一名程序员,我宁愿对如何命名变量有一个简单的规则。

在我努力使用词法分析器和正则表达式来解析数据日志和数据流以插入数据库时​​,我没有发现有一个以数字开头的关键字或变量会使其难以解析 – 只要有尽可能短的路径消除歧义。

因此,对于编译器而言,对程序员而言,它并不是那么容易。