首页 > 解决方案 > Swift REPL 和 swiftc 编译器如何以不同的方式解释语言?

问题描述

Swift 有一个编译器 (swiftc) 和一个 REPL。我喜欢使用 REPL 来学习和使用语言结构。

在我的一个实验中,我发现了一个显着的差异,即“让”的工作方式。

正如我所料,以下是 swiftc 中不允许的,但 REPL 允许。

let x = 10
let x = 20 // ok in REPL

现在我想知道还有什么其他区别。他们在任何地方都有记录吗?

标签: swiftread-eval-print-loop

解决方案


在 REPL 环境中,您希望能够重新声明变量,对吗?否则,随着您继续使用 REPL,并且声明越来越多的变量、let常量、函数、类等等,您将用尽名称来使用!

例如,假设您想尝试字符串插值:

let x = 10
print("x is \(x)!")

过了一会儿,您了解了字符串连接,并且您也想尝试一下。此时,您希望能够重新声明一个let常量x,对吗?

let x = "A"
let y = "B"
print(x + y)

你可以争辩说你可以使用aor b,但随着时间的推移,你会慢慢地用完名字。REPL 是这样设计的,因此您不必非常频繁地重新启动 REPL。

所以每次你提交一些东西时,之前声明的符号也会被覆盖。这在此处记录。

swiftc有一个完全不同的用例——你通常用它来编译更大的程序,而不仅仅是几行代码。在这些情况下,全局作用域的符号会少得多,并且重新声明变量实际上并不实际,因为代码执行从上到下不是线性的。也可能有多个文件可以相互通信。你如何弄清楚什么重新声明了什么?在 REPL 以外的任何地方这样做是没有意义的。

其他 REPL 也具有此功能,例如csharppad.comC#、ghciHaskell 和python,仅举几例。所以当你实现 REPL 时,这真的只是你做的一件普通的事情,而不是 Swift 的特别之处。

实际上,您可以swiftc通过在一个函数中编写这两行代码来重现 REPL 中的行为,因为现在这两行代码在同一个提交中,不会相互覆盖。


推荐阅读