Участник:Alexsmail/Программирование 2020/новый черновик: различия между версиями

Содержимое удалено Содержимое добавлено
дополнение
м →‎REPL: дополнение
Строка 169:
 
=== REPL ===
REPL является сокращением от read-eval-print loop  — цикл "«чтение  — вычисление  — вывод"». REPL является форма организации простой интерактивной среды программирования в рамках средств интерфейса командной строки (CLI). В такой среде пользователь может вводить выражения, которые среда тут же будет вычислять, а результат вычисления отображать пользователю. Названия элементов ''цикла'' обозначают:
 
REPL является сокращением от read-eval-print loop — цикл "чтение — вычисление — вывод". REPL является форма организации простой интерактивной среды программирования в рамках средств интерфейса командной строки (CLI). В такой среде пользователь может вводить выражения, которые среда тут же будет вычислять, а результат вычисления отображать пользователю. Названия элементов ''цикла'' обозначают:
 
• функция read() читает одно выражение и преобразует его в соответствующую структуру данных в памяти;
Строка 179 ⟶ 178 :
 
 
'''TODO:'''
 
Далее, мы должны скомпилировать этот код - — преобразовать его в формат, который доступен для понимания компьютера. В Kotlin мы не компилируем в так называемые машинные коды - — инструкции для конкретного процессора, которые будут непосредственно на нём исполняется, мы компилируем в так называемый ''байткод'' - — промежуточное представление кода. Это некоторый другой язык программирования, ''концептуально'' типа ассемблера. Байткод был изобретён для того, чтобы отвязать написание программы от конкретной операционной системы\процессора на которой она будет бежать. Идея Java Virtaul Machine - — написал один раз - — бежит везде. К примеру, вы можете писать код, компилировать его в байткод на Windows или Mac, а затем запустить байткод под Linux и ваша программа, в теории, работает точно также. См. ещё чуть ниже. На практике это не совсем одно и то же, к примеру если вы работаете с файловой системой, вас могут ожидать сюрпризы, однако, во-первых, ваша программа работает в принципе, а во-вторых, правильно написанная программа будет-таки работать везде.
 
'''Замечание''': Байткод является общим для всех языков, которые используют JVM таких как Java, Scala, Kotlin, Ceylon. Исторически, оно было изобретено для Java, однако другие языки "«компилируется"» в этот же байткод. Таким образом, после компиляции между этими языками нет никакой разницы, JVM не различает между ними.
 
'''Замечание * (Advanced)''': Для Kotlin существует и другие способы компиляции/исполнение, такие как компиляция в JS (JavaScript) или Kotlin Native - — компиляцию минуя байткод. Всё это выходит далеко за рамки этой книги.
 
'''Замечание * (Advanced)''': Когда вы пишите программу на C\C++ вы её пишите под конкретную операционную систему и конкретное железо (hardware). Компилятор преобразует вашу программу в ''инструкции'' для конкретного процессора. Обычно, если вы хотите, чтобы ваша программа работала с другим железом, вам надо её перекомпилировать. Более того, если вы хотите, к примеру, работать с файловой системой, ваш код на C\C++ будет ''другой'' в зависимости от операционной системе. Java Virtual Machine позволяет ''абстрагироваться'' от этого. К примеру, если вам надо обратится к файловой системе, вы не обращаетесь к ней напрямую. Ваша программа бежит в виртуальной машине, она помещена некоторую виртуальную среду. Она вам представляется стандартный способ работать с файлами, т.е.то есть не важно будет ли ваша программа бежать под Linix или Windows вы пишите один и тот же код, вызываете один и тот же API (Application Protocol Interface) у JVM. JVM умеет преобразовывать ваши вызовы для конкретной операционной системы и железа, на которой она стоит. Таким образом JVM является посредником. Вы пишите стандартный код, который не зависит от операционной системы и железа, а JVM преобразовывает его в подходящий для конкретного места, где ваша программа бежит, правильный код. Если код написан правильно, вам безразлично, к примеру, на каком процессоре вы бежите. Однако, при наличии ошибок, ''багов'', поведение системы может отличаться от конкретного процессора. Вы можете как получать разные неправильные результаты в зависимости от процессора, так и некоторые ошибки не будут проявляться на конкретном процессоре. Это также выходит за рамки данной книги.
 
Переходим в директорию с сохранённым файлом.
Строка 205:
 
где
kotlinc - — это сокращение от Kotlin Compiler - — собственно компилтор Котлина;
HelloWorld'''.kt''' - — имя файла, в котором мы сохранили исходный код. Обратите внимание на расширение kt. Kt - — сокращённо Kotlin;
-d - — соращение это destination, место назначение;
MyFirstProgam.jar - — название архива jar-файла, может быть любое;
таким образом '-d MyFirstProgam.jar' обозначает сохранить результат компиляции в jar-е.
 
'''Замечание:''' Формат Jar основан формате Zip. Таким образом, для его распаковки можно использовать любую архиватор, который умеет работать Zip. Для создания архива, однако, я бы советовал использовать стандартную утилиту jar (см. ниже).
Строка 220:
 
где
kotlin - — утилита Kotlin для запуска JVM
classpath - — при запуске JVM сообщить ей, что скомпилированные файлы находятся
MyFirstProgam.jar - — тут
HelloWorld'''Kt''' - — искать функцию main для перадачи управление в файле, исходный код которого был HelloWorld.kt (см. ниже).
 
Ещё раз, kotlin - — это утилита для запуска ''любой'' программы на Котлине, поэтому ей нужно сообщить, где находятся откомпилированные ''наши'' файлы, это мы делаем с помощью ключа -classpath. Почему же мы пишем HelloWorld'''Kt'''?
 
Для того, чтобы разобраться с этим, давайте откроем jar и посмотрим, что там есть. Я советую создать пустую директорию и скопировать туда наш jar-файл, прежде чем продолжить:
Строка 244:
 
где
jar - — утилита JVM по созданию\открытию архивов jar;
xvf - — три ключа к этой утилите;
x - сокращение от eXtract - распаковать файлы;
v - сокращение от verbouse output - распечатать дополнительную инофрмацию на экран во время распаковки;
f - сокращение от file - указание jar-архива (используется почти всегда)
MyFirstProgam.jar - — собственно сам jar
 
На экране (благодаря 'v') будет написано
 
<syntaxhighlight lang="cmd">
Строка 259:
</syntaxhighlight>
 
Т.е.То есть в текущем каталоге у вас появился HelloWorldKt.class. У вас появилась директория META-INF, а в ней ещё два файла MANIFEST.MF и main.kotlin_module. В скобках замечу, если вы не копировали ваш jar в пустой каталог (jarcontent), то HelloWorldKt.class затеряется среди других файлов, которые есть в том каталоге.
 
Итак, что мы видим? Наш исходный файл HelloWorld.'''kt''' скомилировался в HelloWorld'''Kt'''.class. Точную причину добавление постфикса '''Kt''' к имени откомпилированного файла мы рассмотрим в другом разделе, здесь же я скажу, так как ''main()'' была определена как top-level функция и никаких специальных "«инструкций"» мы не делали, то компилятор для всех top-level функций создаёт <исходное имя файла без расширения>'''Kt.class'''. Для Java Virtual Machine Machine наш исходных код не интересен, она видит, что код для запуска находится в HelloWorldKt.class. Именно поэтому выше
<syntaxhighlight lang="cmd">
Строка 271:
Итак, HelloWorldKt.class содержит наш весь исходный код (кроме top-level main function у нас ничего не было). Что же находится в других файлах в директории META-INF?
 
main.kotlin_module - — это файл для утилиты Kotlin для облегчение поиска точки входа в нашу программу, для поиска функции main().
MANIFEST.MF - — этот файл умеет читать JVM при запуске, в котором указана точка входа в программу.
 
Как я говорил, JVM умеет работать хоть с Kotlin, хоть с Java. Мы можем после компиляции запустить JVM другим (стандартным для неё) способом и тогда информация в этом файле будет использована для поиска точки входа в программу (файл main.kotlin_module будет просто проигнорирован в этом случае). Я не привожу этот способ, чтобы ещё больше не запутывать читателя.
Строка 285:
 
 
Первая строчка говорит о том, что формат манифест-файла 1.0. Т.е.То есть формат, в котором дана информация в этом файле, версия этого формата является 1.0. Все виденные мной когда-либо манифест-файлы имеют эту версию, таким образов практической смысловой нагрузки тут нет. Следующая строчка говорит кем именно манифест-файл был сделан. Т.к.Так как этот файл создала утилита kotlinc, которая была, в свою очередь сделана фирмой JetBrains, там и написано JetBrains Kotlin. Это поле просто для информации.
 
Последнее поле самое интересное. Там написано, что искать функцию main() нужно в HelloWorldKt.class. О чём я и говорил выше.