Swift 官博文章翻译 - Swift REPL 交互式解释环境介绍

原文链接:Introduction to the Swift REPL

译者:Mudox

Xcode 6.1 引入了一种新的方式来体验 Swift 语言,那就是通过交互式的读取解释打印循环(Read Eval Print Loop —— REPL)。如果您之前在其他语言里用到过他,您将很快适应 Swift 的 REPL,就算是经验丰富人士在使用过程中也能发现 Swift REPL 的独到之处。

要开始使用它,请在您的 Mac OS X Yosemite 上启动 Terminal.app(在 /Applications/Utilities 里),然后打 “swift” 命令。如果您的系统是 OS X Mavericks 就打 “xcrun swift” 命令。这样您就进入了 Swift REPL 环境了:

// Welcome to Swift version 1.1 (swift-600.0.20.0). Type :help for assistance.
  1> ▌

您只需要像往常那样键入 Swift 的语句,REPL 就会马上执行您的代码。执行的结果会被自动格式化,并加上他们的类型注释(就像 Swift 的变量或者常量声明语法那样)打印在您刚刚键入的代码下:

  1> "100".toInt()
$R0: Int? = 100
  2> let name = "Katherine"
name: String = "Katherine"
  3> println("Hello, \(name)")
Hello, Katherine

Swift REPL 会将每次的计算结果存放在一个特定命名的变量里(即使您的代码并没有把计算结果赋值给具体的变量)。这样您就可以在后续的代码中引用之前的计算结果了:

 4> $R0! + 200      // 这里用 $R0 来引用上面第一行代码的计算结果
$R1: Int = 300

Swift 编译器能判断出您键入的语句是否完整,并在必要时自动提示您继续输入代码以完成语句。它甚至能像 Xcode 那样自动缩进您的代码。比如当您键入如下函数声明代码时:

5> func timesTwo() {
6.     ▌

这里第 6 行为续行提示符(数字后跟一个点),这样您一眼就能明白 REPL 需要您继续键入剩余的代码。此时您可以继续键入余下的代码:

5> func timesTwo() {
6.      return value * 2
7. }▌

这里有三点值得说明下:

多行历史记录

您的代码被提交给编译器的同时,也会被 REPL 环境记录下来。这使得您能更加轻松的修改之前的代码。接着上面的代码,如果您按下回车键就会得到如下的提示:

error: use of unresolved identifier 'value'

和其他环境下的历史记录功能使用方法一样,您可以按下 键来调出之前出入过的代码行。REPL 一次性把我们上面输入的三行代码全部调了出来,并将光标放在的最后一行的末尾。按照下节的指引您就能更正之前的错误了。

每次会话保存的历史记录是能够保留到下次会话的,总共能保存上几百段代码。您可以从代码的首行按向上键(或者 Ctrl+P)调出更早输入的代码,也可以从最后一行代码下面的空行上按 键调出稍近的代码。我们将在下面解释为什么最后一行往下还会出现一行空行。

多行编辑

尽管 Swift REPL 环境表现得像传统的命令行编辑器,它还是提供了多行编辑的能力,这样像输入类定义,函数定义这样经常需要多行一起输入的情况,编辑起来就变得简单了。在上面的函数定义的示例中,在您在最后一行尾按下回车键之前,您可以按下 将光标移动到上面的行,并使用 键移动到参数列表的 ( 后面来修改,添加参数:

5> func timesTwo(▌ {
6.     return value * 2
7. }

现在键入参数声明,然后按 键移动到 ( 之后,然后加上返回类型声明:

5> func timesTwo(value: Int) -> Int▌  {
6.              return value * 2
7. }

在代码中间按下回车键是不能结束代码输入,提交 REPL 的。在中间按回车键只能插入新的一行以便您想在函数或者方法体内加入新行。您这里想要的是移动光标到代码最末尾,您可以按 键两次,或者使用 Emacs 的按键序列 Esc > (Esc 键之后跟一个左尖括号)。在最末尾按下回车键就能将新修改的函数定义提交了:

  8>  timesTwo(21)
$R2: (Int) = 42

自动侦测语句完整性意味着大多数情况下您只管输入心中的代码,让 REPL 来干剩下的脏活。但是某些情况下,您需要一次提交多个语句,因为他们之间相互依赖。设想有下面的代码:

func foo() {
  bar()
}
func bar() {
  foo()
}

如果您只是一行一行的输入上面的代码,当您输入完第三行代码之后就为把第一个函数提交给 REPL 执行,自然会得到如下的警告:

error: use of unresolved identifier 'bar'

当然您可以一行定义两个函数,两个语句之间用分号隔开,但是还有一个更好的方法。在您输入完第三行之后按下 键就会插入并移动到第四行,这是您再就可以继续输入第二个函数的声明了。这两个语句被一次性提交给编译器,达到相互递归的意图。

快速参考

为了帮助你快速开始使用 Swift REPL 环境,面给了常用的编辑和导航快捷键:

按键组合 注释
方向键 上下左右移动光标
Control + F 向右移动光标一个字符,和按下 键一样
Control + B 向左移动光标一个字符,和按下 键一样
Control + P 向上移动光标一个字符,和按下 键一样
Control + N 向下移动光标一个字符,和按下 键一样
Control + D 删除光标键下的字符
Option + Left 将光标移动到上一个单词的开始处
Option + Right 将光标移动到下一个单词的开始处
Control + A 将光标移动到本行首
Control + E 将光标移动到本行末
Delete 删除光标前面的一个字符(这里指主键盘区的回退键 Backspace)
Esc < 将光标移动到第一行的行首
Esc > 将光标移动到最后一行的行末