Blu*_*hen 19 programming-languages
我知道分号表示像Java这样的语言的结尾,但为什么呢?
我被其他人问了很多,我真的想不出一个好方法来解释它如何比使用换行符或空格更好.
Ter*_*ver 19
它们没有发出线路终点信号,它们表示声明结束.
有些语言不需要它们,但是这些语言不允许单行或单个语句上的多个语句跨越多条线(没有像VB的_信号那样的其他信号).
为什么有些语言允许多行语句?理念是空白是无关紧要的(行尾字符是空格).这样可以灵活地设置代码的格式,因为格式化不是语义的一部分.
Ste*_*ase 15
首先,分号是语句分隔符,而不是行分隔符.有些语言使用新行字符作为语句分隔符,但忽略所有空格的语言倾向于使用分号.
语言忽略空格以允许程序员根据自己的喜好格式化源代码.例如,在Java中没有区别
if (welcome)
System.out.println("hello world");
Run Code Online (Sandbox Code Playgroud)
和
if (welcome) System.out.println("hello world");
Run Code Online (Sandbox Code Playgroud)
这不是因为在语言的语法中每个都有一个单独的案例,而是因为空格被简单地忽略了.
这是问题的核心.要理解它,让我们考虑一个没有任何语句分隔符的小语言.它包含以下语句类型:
var x = foo()
y[0, 1] = x
bar()
Run Code Online (Sandbox Code Playgroud)
这里,y是一个二维数组,x并写入其中一个条目y.
现在让我们看一下这些语句,就像编译器会看到它们一样:
var x = foo() y[0, 1] = x bar()
Run Code Online (Sandbox Code Playgroud)
因为没有语句分隔符,所以编译器必须自己识别每个语句的结尾,以理解输入.编译器能够这样做吗?我想在上面的例子中编译器可以做到.
现在,让我们为语言添加另一种语句:
[x, y] = ["hello", "world"]
Run Code Online (Sandbox Code Playgroud)
多重赋值允许程序员一次分配多个值.这条线后,变量x将包含值"hello",而变量y包含"world".这可能非常方便允许函数的多个返回值.现在,它如何与剩余的语句类型一起工作?
请考虑以下语句序列:
foo()
[x, y] = [1, 2]
Run Code Online (Sandbox Code Playgroud)
首先,我们称之为方法foo.之后,我们分配1给x和2给y.至少这是我们打算做的.这是编译器看到的内容:
foo() [x, y] = [1, 2]
Run Code Online (Sandbox Code Playgroud)
编译器能够识别每个语句吗?不,至少有两种可能的解释.第一个是我们想要的.这是第二个:
foo()[x, y] = [1, 2]
Run Code Online (Sandbox Code Playgroud)
这是什么意思?首先,我们称之为方法foo.该方法应该返回一个二维数组.现在,我们将数组写入返回数组[1, 2]中的位置[x, y].
编译器无法识别语句,因为给定输入至少有两种有效解释.当然,这绝不应该在真正的编程语言中发生.在给定的示例中,它可能很容易解决,但重点是,如果没有语句分隔符,则很难设计编程语言.这很难,因为语言设计者必须考虑语句类型的所有可能的排列,以确保语言不含糊.
因此,语句分隔符有助于语言设计者最初设计语言,但更重要的是,它允许语言设计者在将来轻松扩展语言,例如通过添加新的语句类型.这是一件大事,因为一旦用您的语言编写代码,您就不能简单地更改现有语句类型的语法,因为这将导致所有现有代码不再编译.
总而言之,分号是在空格忽略语言时作为语句分隔符引入的,因为设计和扩展具有语句分隔符的语言更容易.
许多语言允许您根据需要放置多少间距.这使您可以控制代码的外观.
考虑:
String result = "asdfsasdfs"
+ "asdfs"
+ "asdfsdf";
Run Code Online (Sandbox Code Playgroud)
因为您可以插入额外的换行符,所以您可以将该行分成几行而不会出现问题.语言仍然需要知道行已完成,这就是你需要分号的原因.