Введение в Swift REPL

Swift REPL

Xcode 6.1 вводит еще один способ поэкспериментировать со Swift - Read Eval Print Loop, или REPL. Разработчики знакомые с интерпретируемыми языками будут чувствовать себя комфортнее в среде командной строки, и даже опытные разработчики найдут несколько уникальных особенностей. Для начала, запустите Terminal.app ( находится /Applications/Utilities) и введите "swift" в строке консоли в OS X Yosemite, или “xcrun swift” в OS X Mavericks. Теперь вы вошли в Swift REPL:

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

Все что нужно сделать, это просто написать выражение на Swift и REPL немедленно выполнит ваш код. Результаты выражения формируются автоматически и отображаются вместе с их типом, также как и результаты объявления констант и переменных. Консольный вывод естественным образом протекает внутри интерактивной сессии:

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

Обратите внимание, что результату первой строки REPL присвоил имя, хотя результат выражения не был явно присвоен чему-либо. Вы можете ссылаться на эти результаты, чтобы использовать их значения в последующих выражениях.

  4> $R0! + 200
$R1: Int = 300

Компилятор Swift распознает незавершённый код, и просит дополнительного ввода при необходимости. Ваш код будет автоматически иметь отступ , как это было бы в Xcode. Например, начиная функцию:

5> func timesTwo() {
6.     

Теперь, приглашение для продолжения состоит из номера строки с последующей точкой вместо знака больше, что указывает на новое выражение, так что вы можете сразу определить, когда вас просят заполнить фрагмент кода. На этом этапе вы можете продолжать писать оставшиеся строки метода:

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

Здесь три примечательных пункта, над которыми нужно поработать: Во-первых, шестая строка была с отступом, но REPL автоматически убрал отступ после того как мы написали закрывающую фигурную скобку. Во-вторых, функция ссылается на параметр, который мы забыли объявить, а также эта функция нуждается в типе возвращаемого значения, так что вам нужно добавить их при декларации. И последнее, даже если вы нажали кнопу "ввод" после последней строки, все еще не поздно, чтобы исправить это.

Многострочная история

После того как код передается компилятору, он также записывается в историю REPL, что делает исправление ошибок тривиальным. Если вы нажали "ввод" в конце декларации неполной функции выше, вам бы показали следующее сообщение:

error: use of unresolved identifier 'value'

Как и в большинстве реализаций истории, вы можете вызвать ваш предыдущий код нажатием стрелки вверх из командной строки. REPL возвращает все три линии в нашем примере, и помещает курсор в конце. Теперь вы можете приступить к редактированию кода, чтобы исправить свою ошибку, как описано в следующем разделе.

Ваша история сохраняется между сессиями и записывает сотни фрагментов кода. Каждый раз, когда вы идете вверх, вы будете двигаться к более ранней записи журнала. Каждый раз когда вы идете вниз, вы будете двигаться к более поздней записи журнала. Пустая строка, которая открывается перед переходом на следующую запись нужна по причине описанной ниже.

Многострочное редактирование

Несмотря на то, что REPL ведет себя как традиционный редактор строки, он также предоставляет удобные функции для работы с многострочным вводом, подобно многим объявлениям класса или функции. В приведенном выше примере, прежде чем нажать "ввод" в последней строке, вы можете нажать стрелку вверх, чтобы переместить курсор к строке объявления, а затем использовать левую стрелку для перемещения курсора сразу к открывающейся скобке со списком параметров:

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

Введите объявление параметра, нажмите правую стрелку для перемещения к закрывающейся скобке, и введите тип результата функции:

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

На данном этапе вы не можете нажать "ввод" для для завершения объявления, потому что вы находитесь в середине блока текста. Нажав здесь "ввод" вы вставите разрыв строки, который может быть полезен, если вы пытаетесь вставить дополнительные строки в тело функции или метода, но здесь вам нужно перейти в конец объявления. Вы можете дважды нажать стрелку вниз для перемещения туда, или использовать последовательность Emacs ESC > ( клавиша escape с последующим знаком больше). Нажав "ввод" в конце последней строки, вы вызовете компиляцию заново объявленной функции, так что он будет готов к использованию.

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

Автоматическое определение завершения выражения означает, что вы можете ввести код, а REPL будет делать правильные вещи в подавляющем большинстве случаев. Есть случаи, однако, когда нужно написать более одного объявления в одно и то же время, потому что они имеют взаимные зависимости. Рассмотрим следующий код:

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

Ввод этих функций строка за строкой, приведет к попытке компилировать первую функцию как только третья строка будет завершена, и, конечно, это приведет к ошибке:

error: use of unresolved identifier 'bar'

Вы можете объявить обе функции в одной строке, чтобы обойти автоматическое обнаружение завершения, которое происходит когда вы нажимаете "ввод", но есть решение лучше. После ввода третьей строки, вы можете нажать стрелку вниз, чтобы вручную подвинуться вниз и написать четвертую строку, а остальные строки можно написать обычным способом. Два объявления будут компилироваться вместе, для достижения желаемой цели взаимной рекурсии.

Быстрый справочник

Чтобы помочь вам начать, вот удобная схема с некоторыми из наиболее часто используемых комбинаций клавиш для редактирования и навигации:

Arrow Keys    Переместить курсор лево/право/вверх/вниз
Control+F     Переместить курсор на один символ вправо, тоже самое что и правая стрелка
Control+B     Переместить курсор на один символ влево, тоже самое что и левая стрелка
Control+N     Переместить курсор в конец следующей строки, тоже самое что и стрелка вниз
Control+P     Переместить курсор в конец предыдущей строки, тоже самое что и стрелка вверх
Control+D     Удалить символ внутри курсора
Option+Left   Переместить курсор в начало предыдущего слова
Option+Right  Переместить курсор в начало следующего слова
Control+A     Переместить курсор в начало текущей строки
Control+E     Переместить курсор в конец текущей строки
Delete        Удалить символ слева от курсора
Esc <         Переместить курсор в начало первой строки
Esc >         Переместить курсор в конец последней строки

Если вам понравилась статья или вы хотите задать вопрос, напишите об этом в комментарии.