为什么Swift不需要分号?[关闭]


20

我通常使用c#或Objective-C进行编码,最近我开始学习Apple的新编程语言-Swift。

我注意到的第一件事是,您不需要在Swift中添加分号来结束一行,但是如果您这样做了-至少从我的测试中可以看出,它不会干扰编译器。

当我写:

int someNumber = 0;

在Objective-C中,分号告诉程序该行结束并且不会掉线到下一行。

使用Swift我可以用

var someNumber:Int = 5

而不添加分号,系统便知道这是行的结尾。

是什么让某些语言可以这样做而其他语言则不能呢?为什么不保持统一的系统,在末尾添加分号?


不是每个人都来自其他语言,所以他们怎么会知道自己不是统一的呢?通过摆脱许多人不喜欢的Objective-C部分,Apple不会通过Swift吸引更多的新程序员吗?
JeffO

2
很多Obj-C兽医对Swift都不满意,因此更喜欢Obj-C。可以在Apple论坛上看到。Swift仅在2014年问世,如果每隔几个月对语言进行一次错误和更改,Swift2.0就会在今年秋天问世。Swift是基于Obj-C的,但其目的是使编码更容易使用更普通的英语来学习。
Memj

旧的编译器实现者只是懒惰和/或必须通过更简单的解析来提高效率。不再需要这个了。它与本地类型推断相同,仅当您的编译器编写者是懒惰的并且不关心开发人员的经验时才使用它。
Ebuall

Answers:


18

是什么让某些语言可以这样做而其他语言则不能呢?为什么不保持统一的系统,在末尾添加分号?

Robert对Swift给出了很好的答案,我将尝试在解析方面添加更多信息,以及为什么使用或不使用分号。

编译程序时,将源文件转换为可执行代码之前需要执行多个步骤,其中第一个步骤是读取和解析。在解析期间,根据语言的语法,您的代码将从字符序列转换为结构化表示。为此,必须以某种方式标识和分隔组成代码的元素(变量,常量,声明等)。当您进行如下声明时:

int someNumber = 0;

这只是一个字符序列,需要以某种方式将其转换为“创建一个称为someNumbertype 的“事物” int并为其分配值0”的概念

这需要确定该语句的确切开始和结束位置。试想一下,如果您有这个:

int someNumber = 0;
int otherNumber = 1;

您需要知道这是两个不同的声明。将;在类似C语言中用于那些,所以解析器读取字符,直到它找到一个,并试图了解当时刚读单个语句。正如罗伯特所说,这允许在同一行中包含多个语句,例如:

int someNumber = 0; int otherNumber = 1;

与将它们写成两行完全一样的效果。

在其他语言中,例如Python,您应该将每个语句放在不同的行中。

x = 3
if x < 10:
   print 'x smaller than 10'
else:
   print 'x is bigger than 10 or equal'

因此,无需添加;,因为该语言本身会阻止您在同一行中添加语句!

还有其他语言,例如LISPScheme,具有将语句分组的非常不同的方式(好吧,它们并不是真正的语句,但是现在让我们忽略它)。因此,所有内容都带有括号:

(define (do-stuff x)
  (begin
    (display (format "value: ~a" x))
    x))

同样,你不需要;仅仅因为你使用相同的符号()()的东西,在其他语言{}:等有人谁只知道Lisp的语法可能会问你:为什么你需要;在你的陈述结束?

只是添加一个陌生的示例:OCaml不仅在语句末尾有分号,而且还有两个分号!

let rec fact x =
    if x <= 1 then 1 else x * fact (x - 1);;

为什么?我不知道。:)

设计不同的语言具有不同的目的和理念。如果所有语言都共享相同的语法和约定,则它们可能只会允许您以相同的方式执行相同的操作。


4
好的结束语。
Thomas Eding

很好的例子,但是您没有回答问题。
Robo Robok

附加数据点:一些语言对C样式家族采取了相反的方式:例如,HyperTalk使用换行符作为行的硬端(而不是分号),并且如果要继续执行语句,则需要转义换行符多行。有趣的是,C自己的预处理器也可以这样工作。
uliwitness

11

使用换行符代替分号来分隔语句的结尾。

在《语言指南:基础知识》中说:

与许多其他语言不同,Swift不需要您在代码中的每个语句后写分号(;),尽管您可以根据需要这样做。但是,如果要在一行上编写多个单独的语句,则需要使用分号。

为什么?因为这就是语言设计师想要的方式。

上面的第二句话暗示了为什么不需要分号。大多数语句是单行。 观察此冒泡排序示例;单行语句和无分号的组合使语法非常干净,类似于VB,但较不冗长:

func bubbleSort<T:Comparable>(inout list:[T]) {
    var done = false
    while !done {
        done = true
        for i in 1..<list.count {
            if list[i - 1] > list[i] {
                (list[i], list[i - 1]) = (list[i - 1], list[i])
                done = false
            }
        }
    }
}

由于Swift中的语句通常以换行符结尾,因此减少了用分号标记语句结束的需要。其他使用分号的语言则无法正常工作。您可以自由编写多行语句,但是编译器知道该语句已结束的唯一方法是将分号放在它的末尾。

当语句不在换行符处结束时,您必须将换行符放置在Swift编译器可以识别为上一行的延续的位置:

let s2 = str
        .lowercaseString
        .replace("hello", withString: "goodbye")

2
最后一条语句为假,没有放置换行符的特定位置。最好使代码行缩进并对齐以提高可读性。
尼科·阿隆索

有趣的事实:这对错误报告有连锁反应。许多C编译器(特别擅长clang)使用分号来查找语法错误的语句结尾,并且可以使用该信息来报告丢失的闭合圆括号,这些圆括号更靠近其实际丢失的位置。缺少分号,在Swift中出错通常会导致以下行被压缩到包含错误的前身中,并导致真正的错误消息。
uliwitness
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.