**GOLANG ПОЛНЫЙ КУРС ДЛЯ НАЧИНАЮЩИХ | ЧАСТЬ 1 | ОСНОВЫ ПРОГРАММИРОВАНИЯ — Transcript & Summary | SozAI**
Source: https://sozai.app/transcript/golang-full-course-beginners-part1-basics/

Полный бесплатный курс по Go для начинающих: установка, настройка окружения и основы программирования.

## Key Takeaways

- Курс полностью бесплатен и ориентирован на практическое освоение Go.
- Для разработки рекомендуется использовать Visual Studio Code с расширением Go.
- Настройка окружения включает установку редактора и языка, а также их интеграцию.
- Домашние задания и учебные проекты доступны в открытом и приватном Telegram-канале.
- Видео содержит подробные инструкции по установке и настройке на разных ОС.

## What the video covers

- Введение в курс программирования на Go для начинающих с целью создания полноценного приложения.
- Рекомендации по подписке на YouTube и Telegram для получения домашних заданий и общения.
- Обзор установки и настройки рабочего окружения: редактор кода Visual Studio Code и язык Go.
- Пояснение преимуществ VS Code как редактора кода для коммерческой разработки.
- Пошаговая инструкция по скачиванию и установке VS Code и Go на Windows, macOS и Linux (Ubuntu).
- Интеграция Go с VS Code через установку расширения и проверка работоспособности через терминал.
- Создание и открытие рабочей папки для написания кода в VS Code.
- Объяснение разницы между редактором кода и языком программирования, а также запуск кода.
- Поддержка и мотивация автора для продолжения курса и выполнения домашних заданий.
- Навигация по видео с помощью тайм-кодов для удобства изучения.

## Chapters

1. 00:00 Введение и обзор курса
2. 25:00 Установка и настройка Visual Studio Code
3. 45:00 Установка языка программирования Go
4. 60:00 Интеграция Go с VS Code и проверка установки
5. 70:00 Создание рабочей папки и начало работы с кодом

Answers

## Questions about this video

Для чего нужен редактор кода в курсе по Go?

Редактор кода нужен для удобного написания и редактирования файлов с программным кодом, с подсветкой синтаксиса, автодополнением и подсветкой ошибок, что облегчает разработку.

Почему рекомендуется использовать Visual Studio Code для разработки на Go?

VS Code бесплатен, легковесен, работает на слабых компьютерах и поддерживает все необходимые функции для коммерческой разработки, включая расширение для Go.

Где можно найти домашние задания и учебные проекты к курсу?

Домашние задания и исходные коды доступны в открытом Telegram-канале автора, а разборы и видео с объяснениями — в приватном сообществе.

## Full Transcript — Download SRT & Markdown

00:00

Speaker A

Всем привет. Добро пожаловать на первую часть полного курса Понг для начинающих. В этой части мы рассмотрим основы программирования на Go, а в будущих частях погрузимся глубже в сам язык и в конечном счёте напишем своё полноценное приложение. После полного прохождения всего курса ты в достаточной мере овладеешь необходимыми навыками для настоящей коммерческой разработки. Поэтому не забудь подписаться на мои YouTube и Telegram-каналы, чтобы не пропустить новые выпуски. Настоятельно рекомендую после каждой пройденной темы решать домашнее задание. Домашнее задание вы найдёте в моём открытом Telegram-канале. Общение с коллегами по изучению программирования, конспекты пройденных тем и видео с разбором и решением домашних заданий вы найдёте в приватном сообществе на уровне техник. Все ссылочки лежат в описании к данному видео. В конце каждой части мы будем закреплять полученные знания при помощи написания учебных проектов. И данная часть не является исключением. Задание на учебный проект и исходный код решения всё также в моём открытом Telegram-канале. А видео с написанием и объяснением написанного на учебном проекте кода всё также в приватном сообществе. Курс полностью бесплатен. Все домашние задания и исходные коды бесплатны. Навигация по темам при помощи тайм-кодов, конечно же, прилагается. Очень вас попрошу подписаться как на YouTube, так и на Telegram-канал. Это бешеная мотивация для меня выпускать следующие части как можно раньше. Не будем затягивать. Серия и так получилась не самая коротенькая. Поехали.

00:14

Speaker A

[Музыка] Первое, что нам необходимо будет сделать, — это настроить рабочее окружение. Нам необходимо будет скачать некоторый софт, который позволит нам в дальнейшем писать свои собственные программы. На первых порах всё, что нам нужно будет скачать, — это редактор кода и сам язык программирования. Для чего нам нужен редактор кода и для чего нам нужен язык программирования? Редактор кода нам нужен для того, чтобы редактировать файлы с кодом. То есть, по сути, мы могли бы это делать хоть в блокноте, да хоть в Ворде, но в редакторе кода это делать гораздо удобнее, потому что он располагает всей необходимой функциональностью для того, чтобы поддерживать наше написание кода. Подсветка синтаксиса, автодополнение, подсветка ошибок — всё это будет нам очень сильно помогать в разработке. В блокноте, как вы понимаете, этого нет. Есть различные редакторы кода, но я советую вам выбрать именно Visual Studio Code. Далее редактор кода Visual Studio Code я буду сокращённо называть VS-код, потому что VS-код — это более распространённое название. Почему в качестве редактора кода я советую выбрать именно VS-код? Потому что он бесплатный, потому что он легковесный, то есть будет запускаться даже на слабеньких компьютерах и довольно хорошо там работать. И потому что он отвечает всем нормам коммерческой разработки современной. То есть я на нём писал как ПД-проекты, так и коммерческие проекты, так и в найме я работал и использовал Visual Studio Code. Он отлично подходит для всех задач. Но вот мы написали с вами код, отредактировали файлы с кодом. Но что с ними делать? Их же нужно как-то запускать этот код. Кто будет запускать этот код? Редактор кода — это просто редактор кода. Это просто, по сути, усовершенствованный блокнот, то есть навороченный блокнот, с помощью которого удобно редактировать код. Но запускать-то код как? А вот запускать код мы с вами будем с помощью языка программирования. То есть мы будем вызывать язык программирования и указывать ему, какие конкретно файлы с кодом нужно запустить. Язык программирования будет эти файлы с кодом запускать, выполнять, и мы будем видеть результат выполнения наших программ. Сейчас я покажу, как настроить рабочее окружение в зависимости от того, какая у вас операционная система. То есть, повторюсь, под настройкой рабочего окружения я подразумеваю установку редактора кода, чтобы мы с вами могли писать программы, и установку языка программирования, чтобы мы написанные программы могли запускать. Можете смело открывать тайм-коды и прыгать на вашу операционную систему. То есть, если у вас Windows, то прыгайте на тайм-код с Windows. Если у вас macOS, то прыгайте на тайм-код с macOS. И если у вас Linux, то прыгайте на тайм-код с Ubuntu. В качестве Linux-дистрибутива, как самый популярный для гайда, я выбрал [музыка] Ubuntu. Чтобы скачать VS-код на Windows, просто пишем в браузере в поисковой строке VS код скачать. Переходим по первой же ссылке и вот выбираем версию для Windows. Автоматически начинается загрузка. Просто ждём, пока файл загрузится. Открываем. Соглашаемся со всеми условиями. Можете выбрать нестандартный путь, куда установить редактор кода. Я выберу стандартный, оставлю. Не буду создавать папку в меню Пуск. Зачем? И здесь мы можем настроить нашу установку. Я бы хотел создать значок на рабочем столе и добавить действие "Открыть с помощью кода" в контекстное меню. Что это значит? Допустим, у вас есть какая-нибудь папка, и в этой папке лежат файлы с кодом, и вы сможете просто правой кнопкой мыши нажать по этим файлам и нажать "Открыть с помощью кода". Тем самым вы откроете сразу файл с кодом в нашем редакторе кода. Поэтому просто ставим все галочки и жмём далее. Всё, устанавливаем. Вот мы скачали, установили наш редактор кода. Теперь мы можем его запустить. Просто оставляем тут галочку, нажимаем завершить. Открывается приветственное окно нашего редактора кода. Тут, в принципе, можно выбрать какие-то настройки. Я выберу просто тему. Вот здесь вот можно нажать "Выбрать тему" и выберу белую. Вы можете оставить чёрную, если вы хотите. Всё, в принципе, это приветственное окно можно закрыть. Поздравляю, мы с вами скачали, установили редактор кода. Теперь нужно скачать и установить сам язык программирования. Тут тоже всё довольно просто. Пишем в поисковой строке GoLang скачать.

00:31

Speaker A

[Аплодисменты] Открываем первую же ссылку и тут выбираем установщик для Windows. Ждём, пока скачается файл. Открываем, нажимаем далее. Соглашаемся с условиями использования. Опять же можно выбрать нестандартный путь, куда вы хотите установить язык программирования. Я опять же выберу стандартный. Всё, нажимаем установить. Поздравляю, мы установили язык программирования. Теперь нам нужно подружить редактор кода с языком программирования, чтобы редактор кода знал, где находится язык программирования, чтобы мы могли запускать написанные нами программы. Для этого нужно зайти вот сюда, нажать кнопочку и написать в поисковой строке go. Это расширение для GoLang, которое предоставляет большую функциональность для удобства разработки. Нажимаем скачать. Доверяем разработчику этого расширения. Всё, расширение скачано. Теперь нам нужно закрыть эту вкладку. Теперь нам нужно нажать вот эту вот комбинацию клавиш Ctrl, Shift, P. Нажимаем её и тут пишем go, двоеточие go pass. Нажимаем сюда. Всё. Видим вот эти вот зелёные логи. Это значит, что у нас успешно наш редактор кода подружился с нашим языком программирования. Для того, чтобы это всё проверить, можем нажать сюда вот view или же, если у вас VS-код на русском языке, то "Вид". И тут будет терминал. И тут нужно написать go. Всё. Если вы видите вот такой вот вывод, это значит, что язык программирования Go у нас скачан, и мы можем с ним работать. Можно написать go version, и вы увидите версию языка программирования, которую мы установили. Вот. Go 1.24.1. И как мы видим, мы именно такую скачали. Вот она. Go 1.24.1. Вот мы с вами скачали редактор кода. Вот мы с вами скачали язык программирования. Теперь всё, что осталось сделать, — это опять же вернуться в наш редактор кода, и нам необходимо выбрать папку, в которой мы с вами будем писать код. Сейчас у нас никакой папки нет, поэтому просто можем создать её на рабочем столе. То есть я вот тут вот нажимаю создать папку, пишу её, назову её study, то есть как папка, в которой мы будем с вами обучаться. Вот она у нас тут. Вот она папка study на рабочем столе. Теперь возвращаемся в редактор кода, нажимаем "Открыть папку". И вот на рабочем столе выбираем папку study. Выбор папки. Доверяем разработчику.

00:40

Speaker A

Все ссылочки лежат в описании к данному видео. В конце каждой части мы будем закреплять полученные знания при помощи написания учебных проектов. И данная часть не является исключением. Задание на учебный проект и исходный код решения всё также в моём открытом

00:54

Speaker A

Telegram-канале. А видео с написанием и объяснением, написанного на учебном проекте кода, всё также в приватном сообществе. Курс полностью бесплатен.

01:02

Speaker A

Все домашние задания и исходные коды бесплатны. Навигация по темам при помощи тайм-кодов, конечно же, прилагается.

01:08

Speaker A

Очень вас попрошу подписаться как на YouTube, так и на Telegram-канал. Это бешеная мотивация для меня выпускать следующие части как можно раньше. Не будем затягивать. Серия и так получилась не самая коротенькая. Поехали.

01:21

Speaker A

[музыка] Первое, что нам необходимо будет сделать - это настроить рабочее окружение. Нам необходимо будет скачать некоторый софт, который позволит нам в дальнейшем писать свои собственные программы. На первых порах всё, что нам нужно будет скачать - это редактор кода и сам язык

01:38

Speaker A

программирования. Для чего нам нужен редактор кода и для чего нам нужен язык программирования? Редактор кода нам нужен для того, чтобы редактировать файлы с кодом. То есть, по сути, мы могли бы это делать хоть в блокноте, да хоть в ворде, но в редакторе кода это

01:51

Speaker A

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

01:56

Speaker A

Подсветка синтаксиса, автодополнение, подсветка ошибок. Всё это будет нам очень сильно помогать в разработке. В блокноте, как вы понимаете, этого нет.

02:04

Speaker A

Есть различные редакторы кода, но я советую вам выбрать именно Visual Studio Cд. Далее, редактор кода Visual Studio Cд я буду сокращённо называть VS-код, потому что VS-код - это более распространённое название. Почему в качестве редактора кода я советую выбрать именно VS-код? Потому что он

02:19

Speaker A

бесплатный, потому что он легковесный, то есть будет запускаться даже на слабеньких компьютерах и довольно хорошо там работать. И потому что он отвечает всем нормам коммерческой разработки современной. То есть я на нём писал как пд-проекты, так и коммерческие проекты,

02:34

Speaker A

так и в найме я работал и использовал Visual Studio Cд. Он отлично подходит для всех задач. Но вот мы написали с вами код, отредактировали файлы с кодом.

02:43

Speaker A

Но что с ними делать? Их же нужно как-то запускать этот код. Кто будет запускать этот код? Редактор кода - это просто редактор кода. Это просто, по сути, усовершенствованный блокнот, то есть навороченный блокнот, с помощью которого удобно редактировать код. Но

02:54

Speaker A

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

03:08

Speaker A

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

03:23

Speaker A

программирования, чтобы мы написанные программы могли запускать. Можете смело открывать тайм-коды и прыгать на вашу операционную систему. То есть, если у вас Winda, то прыгайте на тайм-код с Wндой. Если у вас МакоOS, то прыгайте на тайм-код с Макуэсом. И если у вас Linux,

03:36

Speaker A

то прыгайте на тайм-код с Убунту. В качестве Linux дистрибутива, как самый популярный для гайда, я выбрал [музыка] Убунту. Чтобы скачать VS-код на Windows, просто пишем в браузере в поисковой строке VS код скачать. Переходим по первой же ссылке и

03:55

Speaker A

вот выбираем версию для Windows. Автоматически начинается загрузка. Просто ждём, пока файл загрузится. Открываем. Соглашаемся со всеми условиями. Можете выбрать нестандартный путь, куда установить редактор кода. Я выберу стандартный, оставлю. Не буду создавать папку в меню пуск.

04:21

Speaker A

Зачем? И здесь мы можем настроить нашу установку. Я бы хотел создать значок на рабочем столе и добавить действие.

04:28

Speaker A

Открыть с помощью кода в контекстное меню. Что это значит? Допустим, у вас есть какая-нибудь папка, и в этой папке лежат файлы с кодом, и вы сможете просто правой кнопкой мыши нажать по этим файлам и нажать открыть с помощью код.

04:40

Speaker A

Тем самым вы откроете сразу файл с кодом в нашем редакторе кода. Поэтому просто ставим все галочки и жмём далее. Всё, устанавливаем. Вот мы скачали, установили наш редактор кода. Теперь мы можем его запустить. Просто оставляем тут галочку, нажимаем завершить. Открывается приветственное

04:57

Speaker A

окно нашего редактора кода. Тут, в принципе, можно выбрать какие-то настройки. Я выберу просто тему. Вот здесь вот можно нажать выбрать тему и выберу белую. Вы можете оставить чёрную, если вы хотите. Всё, в принципе, это приветственное окно можно закрыть.

05:11

Speaker A

Поздравляю, мы с вами скачали, установили редактор кода. Теперь нужно скачать и установить сам язык программирования. Тут тоже всё довольно просто. Пишем в поисковой строке Goeng скачать.

05:22

Speaker A

[аплодисменты] Открываем первую же ссылку и тут выбираем установщик для Windows. Ждём, пока скачается файл.

05:37

Speaker A

Открываем, нажимаем далее. Соглашаемся с условиями использования. Опять же можно выбрать нестандартный путь, куда вы хотите установить язык программирования. Я опять же выберу стандартный. Всё, нажимаем установить.

05:50

Speaker A

Поздравляю, мы установили язык программирования. Теперь нам нужно подружить редактор кода с языком программирования, чтобы редактор кода знал, где находится язык программирования, чтобы мы могли запускать написаны нами программы. Для этого нужно зайти вот сюда, нажать кнопочку и написать в поисковой строке

06:07

Speaker A

go. Это расширение для голенга, которое предоставляет большую функциональность для удобства разработки. Нажимаем скачать. Доверяем разработчику этого расширения. Всё, расширение скачано.

06:19

Speaker A

Теперь нам нужно закрыть эту вкладку. Теперь нам нужно нажать вот эту вот комбинацию клавиш Ctrl, Shift P.

06:25

Speaker A

Нажимаем её и тут пишем go, двоеточие go Pasз. Нажимаем сюда. Всё. Видим вот эти вот зелёные логи. Это значит, что у нас успешно наш редактор кода подружился с нашим языком программирования. Для того, чтобы это всё проверить, можем нажать сюда вот

06:41

Speaker A

view или же если на русском языке у вас VS-код, то вид. И тут будет терминал.

06:49

Speaker A

И тут нужно написать go. Всё. Если вы видите вот такой вот вывод, это значит, что язык программирования Go у нас скачан, и мы можем с ним работать. Можно написать go verion, и вы видится версия языка программирования, которую мы

07:03

Speaker A

установили. Вот. Go 1241. И как мы видим, мы именно такую скачали. Вот она. Go 1 241. Вот мы с вами скачали редактор кода. Вот мы с вами скачали язык программирования.

07:15

Speaker A

Теперь всё, что осталось сделать - это опять же вернуться в наш редактор кода и нам необходимо выбрать папку, в которой мы с вами будем писать код. Сейчас у нас никакой папки нету, поэтому просто можем создать её на рабочем столе. То есть я

07:28

Speaker A

вот тут вот нажимаю создать папку, пишу её, назову её studди, то есть как папка, в которой мы будем с вами обучаться. Вот она у нас тут. Вот она папка стади на рабочем столе. Теперь возвращаемся в редактор кода, нажимаем

07:43

Speaker A

"Открыть папку". И вот на рабочем столе выбираем папку стадия. Выбор папки. Доверяем разработчику, то есть сами себе в данном случае. Всё, мы с вами скачали редактор кода, язык программирования, создали папку для написания кода. Осталось только писать код в редакторе кода и с помощью языка

08:02

Speaker A

программирования запускать. Смотрите тайм-коды, прыгайте сразу на написание первой программы. [музыка] Для того, чтобы разрабатывать на, первым делом нам необходимо установить пакетный менеджер Brew. Brew нам поможет скачать язык программирования. Брю нам поможет скачать редактор кода. И в будущем BRW

08:22

Speaker A

нам очень сильно будет помогать устанавливать различные зависимости. Поэтому для разработки на Macos первым делом мы скачиваем Brew. Для того, чтобы скачать Brew, мы просто пишем в поисковой строке Brew скачать. Переходим по первой же ссылке и видим здесь команду, которую нам необходимо

08:41

Speaker A

скопировать и вставить в терминал. Вот просто нажимаем Launchpad, пишем тер. Вот он наш терминал. Нажимаем, вот он открывается. Вставляем команду, скопирован. Нажимаем Enter.

08:54

Speaker A

Вводим пароль. Нажимаем ещё раз Enter. Вот теперь он нам пишет предупреждение, что нам необходимо выполнить некоторые команды. И как раз-таки вот здесь вот эти самые команды нам пишутся. Вот эти три команды. Их просто можно выделить, скопировать, потом вставить и нажать

09:13

Speaker A

опять Enter. Готово. Теперь можем написать в консоли Brew и увидим, что у нас установлена наша утилита. Дальше с помощью BRW нам необходимо скачать Visual Studio CД, то есть наш редактор кода. Как это сделать? Просто так же пишем в поисковой строке Brew скачать

09:32

Speaker A

Visual Studio Cд. Вот первая же ссылка. И вот наша команда, которую также необходимо скопировать и потом вставить в терминал. Вставляем в терминал, нажимаем Enter. Всё, поздравляем, мы с вами установили Visual Studio Cд. Теперь мы сможем его открыть прямо из лаунчпада.

09:52

Speaker A

Пишем Visual. И вот сразу нам советуют. Открываем. открыть. И нас встречает вот такое вот приветственное окно. Тут, помимо прочего, я выбираю только изменить темку. Тут ещё разные есть варианты настройки вашего редактора. Я просто поменяю тему. То есть вы можете оставить

10:13

Speaker A

тему, какую есть, можете выбрать немножко другую. Я вот выберу светлую тему. Всё, можем закрыть эту вкладку. И мы установили, скачали с вами редактор кода. Теперь нам необходимо скачать сам язык программирования, чтобы написанный код в редакторе кода мы могли запускать.

10:28

Speaker A

То же самое всё с помощью брю. Пишем в поисковой строке бр скачать. Первая же ссылка. Вот команда.

10:39

Speaker A

Копируем её, переходим в терминал, вставляем и нажимаем Enter. Можем теперь проверить, что мы всё-таки корректно установили язык программирования. Для этого пишем в терминал go пробел Version.

10:52

Speaker A

Всё, у нас вводится версия скачанного нам языка программирования, и мы успешно установили сам язык программирования.

10:58

Speaker A

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

11:19

Speaker A

расширения. Готово. Теперь всё, что нам осталось сделать - это нажать комбинацию клавиш Command Shift P. Вот она у нас подсвечивается. Command Shift P. И тут написать go, двоеточие go paz и нажать сюда. Всё, поздравляю. Теперь мы подружили наш редактор кода с языком

11:40

Speaker A

программирования. Мы скачали редактор кода, мы скачали язык программирования, и мы их друг с другом познакомили. Мы с вами скачали редактор кода, и мы с вами скачали язык программирования. Теперь нам осталось перейти обратно в редактор кода и открыть папку, в которой мы с

11:55

Speaker A

вами новый код, новые программки будем писать. Сейчас у нас никакой папки нету, нам необходимо её создать. Для этого переходим в finder, нажимаем Finder, настройки, переходим во вкладку сайт и ставим галочку на нашу домашнюю директорию, чтобы она у нас появилась в

12:12

Speaker A

избранных папках нашего проводника. Переходим в нашу домашнюю директорию и тут создаём папочку. Я назову её стади, потому что это папка, в которой мы будем писать код в целях обучения. Вот наша папочка studди.

12:26

Speaker A

Переходим обратно в редактор кода, нажимаем открыть папку и переходим вот в нашу домашнюю директорию и переходим в нашу папочку Study. Нажимаем открыть, доверяем разработчику, то есть самим себе. Готово. Всё, окружение на Макос настроено. И можете смело прыгать на тайм-код написания первой программы.

12:49

Speaker A

[музыка] Перед тем, как что-либо делать на Убунте, я сначала обновлю все её пакеты, потому что у меня свежая установка и хотелось бы, чтобы все пакеты были в актуальном состоянии. И напишу суда update, чтобы подтянуть всю информацию с удалённых репозиториев, чтобы моя

13:06

Speaker A

локальная убунта понимала, какие вообще есть новые пакеты. и суда upgrade, чтобы всю эту информацию, если у Бунта узнает о каких-то новых пакетах, чтобы она все их взяла и обновила.

13:22

Speaker A

Пароль. Да, всё, теперь мы готовы работать дальше с субунтой. Переходим в браузер. И чтобы скачать редактор кода, пишем довольно просто VS-код скачать.

13:38

Speaker A

Заходим по первой же ссылке и тут выбираем пакет для Линнукса, который нам подходит. В данном случае у нас Убунта, поэтому DEPпакет. Автоматически начинается установка. Установка завершена. Можем открывать Убунты. Довольно удобный, стандартный установщик деп-пакетов. И мы воспользуюсь. Установить.

14:00

Speaker A

Установить. Пароль. Установлено. можем закрыть и найти в списке приложений Visual Studio Code. Открывается приветственное окно.

14:16

Speaker A

Тут, в принципе, всё, что нас интересует на данный момент, это темку можно выбрать вот светлую, тёмную, контрастную. Я выберу обычную светлую тему. Всё, теперь можно это окно закрывать. Поздравляю, мы установили редактор кода на Убунту. Теперь нужно установить сам язык программирования.

14:32

Speaker A

для того, чтобы установить язык программирования, пишем также в адресной строке Going скачать. Переходим по первой же ссылке нажимаем Download и тут выбираем версию под Linux. Дожидаемся, пока у нас установится этот архив. Архив установлен. Теперь нам нужно его разархивировать. Для того, чтобы

14:57

Speaker A

разархивировать скачанный нами язык программирования, переходим в терминал. Переходим в папку, куда мы с вами скачали этот самый архив, то есть это папка загрузки. И вот мы видим тут наш самый этот архив. Для того, чтобы его разархивировать, пишем судо TAR. Та -

15:14

Speaker A

это утилиты для работы с архивами. Передаём еф X, Z и F. X - это значит, что мы хотим извлечь все файлы. Z - это значит, что мы будем под капотом использовать утилиту GZP. И F значит, что мы просто хотим путь до файла

15:27

Speaker A

указать. Вот, то есть путь до файла. и указываем, куда именно мы хотим разархивировать наши с вами файлы, то есть user local. Пароль вводим. Готово. Теперь можем проверить, что у нас в папочке user local лежит go. User local. Можем посмотреть дальше.

15:48

Speaker A

Go. Вот в этой папке Go лежат ещё другие файлы, в том числе папка Bin. В папке BIN вот он наш самый скомпилированный, собранный язык программирования. То есть мы даже его вот так вот можем выбрать, достучаться до него и проверить версию. User local

16:03

Speaker A

go bein go версион. Бам. Всё, мы можем даже версию проверить. То есть всё полностью рабочий язык программирования мы скачали. Ну а каждый раз писать такой длинный путь неудобно. Поэтому мы добавим вот эту вот папку в переменную среды для убунты, чтобы каждый раз,

16:17

Speaker A

когда мы просто писали гоo, то есть вот эту последнюю часть, то автоматически среди прочих папок убунта искала вот этот вот бинардик в данной папке, и она его будет находить, потому что он там есть. Давайте перейдём в нашу домашнюю

16:30

Speaker A

директорию. И нужно нам отредактировать файл баш Rrc. Если у вас вдруг ZSH, если вы вдруг ставили какие-то кастомные терминалы на ZSH, тогда нужно будет редактировать файл ZSHRC. Я пользуюсь для редактирования файлов Виimмом, но его тут сейчас нет, поэтому я его

16:47

Speaker A

[аплодисменты] установлю. Всё. Теперь открываем этот наш самый баш RC файл, переходим в самый низ и тут пишем экспорт pass равно pass двоеточие user local.

17:07

Speaker A

Гобин. Всё. Теперь каждый раз, когда мы будем писать просто го, у нас будет искаться вот в этой вот папке, вот в этой вот папке бинарник с гошкой. Ну давайте проверим. Сохраняем, выходим и активируем наш новый баш RC файл. Теперь

17:24

Speaker A

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

17:36

Speaker A

Для этого в расширениях, то есть нажимаем сюда, нажимаем в поисковой строке, пишем go и скачиваем вот самое первое расширение. Доверяем разработчику расширения. Всё, оно у нас установлено.

17:50

Speaker A

Теперь всё, что нам осталось сделать - это нажать вот эту вот комбинацию клавиш Ctrl Shift P и написать Go двоеточек current GoPs.

18:00

Speaker A

Нажимаем. Всё. Видим уведомление о том, что у нас успешно добавился в наш редактор. И теперь мы можем проверить, что из нашего редактора кода этот самый доступен. То есть нажимаем опять терминал и пишем go. Всё, goверсион можно написать. видим, что вызывает. У

18:19

Speaker A

нас показывается версия, которую мы с вами установили. Всё, мы с вами скачали редактор кода. Мы с вами скачали язык программирования. Всё, что осталось сделать, это вернуться в наш редактор кода и выбрать папку, в которой мы с вами будем разрабатывать, в которой мы с

18:32

Speaker A

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

18:42

Speaker A

учиться программированию. О'кей, вот наша папка. Осталось её открыть в редакторе кода. Нажимаю открыть папку. И вот заходим на рабочий стол. Вот она, наша папка стади. Выбираем её и нажимаем "Открыть". Всё. Поздравляю, мы с вами настроили рабочее окружение по дубунту.

18:58

Speaker A

Можете по тайм-коду сразу прыгать на написание первой [музыка] программы. Всё, мы с вами открыли редактор и открыли папку. Теперь в ней мы можем создать свой первый файл с кодом. А для этого мы можем нажать вот сюда вот на плюсик. То есть вот тут

19:14

Speaker A

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

19:28

Speaker A

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

19:45

Speaker A

myfile.go. И вот уже создался файл с кодом. То есть всё, что мы тут будем писать - это код. Как вы видите, у меня уже сразу какие-то ключевые слова пошли, непонятные уже. Редактор кода сам мне их подсказывает. Мы, конечно, можем

19:58

Speaker A

оставить название файлу и Myфайл и какой угодно. И этот код даже будет работать, мы его сможем запускать. Но в Goleng принято, есть такая конвенция, что файлы с кодом, от которых программа начинает своё выполнение, необходимо называть main. Давайте будем следовать этой

20:15

Speaker A

конвенции, сразу привыкать, поэтому опять же удалим этот файл и создадим новый уже с названием main. Ну и так как мы нанге пишем main.go. Всё, мы создали с вами файл.

20:26

Speaker A

Теперь, чтобы написать свою первую программу, нам необходимо объявить пакет. Я сейчас напишу строчки кода, а потом объясню их каждую отдельно. Пишем package main, потом пишем funkчки. Что тут вообще произошло? То есть мы с вами объявили пакет. Что такое

20:47

Speaker A

пакет вообще в Goldeng? На самом деле вам станет понятно далее. Пока на этом можно сильно не заострять внимание.

20:53

Speaker A

Просто нужно запомнить, что в начале файла каждого нам необходимо объявить, что это за пакет. Сейчас мы с вами находимся в самом главном файле программы, в самом основном файле программы, поэтому мы называем этот пакет main. Опять же, что именно такой

21:09

Speaker A

пакет, станет понятно далее, пока можно это не сильно застрять на это внимание. Дальше идут слова main. Что это вообще такое? Это значит, что мы с вами объявляем кусок кода, в котором программа будет начинать своё выполнение. Почему именно из этого куска

21:26

Speaker A

кода? Потому что он называется main. То есть вообще, как вот каждое слово тут разобрать? То есть фун - это какой-то обособленный кусок кода, по сути. То есть это функция. Функция обособленный кусок кода. Main - это значит, что это

21:39

Speaker A

главная функция. Главная функция в главном пакете, в главном файле. Это значит, что конкретно вот с четвёртой строчки, да, вот я вот тут, что бы я тут не писал, именно отсюда начнётся выполнение моей программы, всей вообще программы. То есть у меня может быть

21:56

Speaker A

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

22:08

Speaker A

Между ними вот если на неё просто нажать, например, на открывающую, видно, как сразу начинает подсвечиваться и закрывающая. Что это значит? Это значит, что это какой-то отдельный кусок кода.

22:19

Speaker A

Всё, что будет происходить между этими двумя скобками - это какой-то кусок кода отдельный, который относится вот к этой функции main. То есть функция, опять же, пока что на данный момент нам хватит понимания, что функция или сокращённа Fun - это просто какой-то кусок кода

22:37

Speaker A

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

22:53

Speaker A

кусок кода. Но программа начнёт своё выполнение именно отсюда. Не отсюда она его начнёт, а именно отсюда. Почему?

23:01

Speaker A

Потому что называется main. То есть этим самым мы языку программирования говорим, что нужно выполнять код, начинать выполнение программы конкретно с этого куска кода. Абобу я пока сотру. И вот, если вы видите, тут какое-то подчёркивание странное. И опять же, мы

23:17

Speaker A

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

23:32

Speaker A

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

23:46

Speaker A

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

24:00

Speaker A

программа начнёт выполнение кода именно отсюда. Давайте теперь напишем первую программу. Принято вообще в программировании самую первую программу писать ту, которая просто нам будет выводить на экран текст Hello World. То есть в переводе с английского это как бы Привет, мир. Почему так принято? Да

24:18

Speaker A

потому что самая первая программа, написанная в этом мире, выводила именно текст Hello World на условный экран, который был вот тогда ещё давно. Там, конечно, были не наши 2К, 4К там мониторы 120 Гц, но некоторые их аналоги. Давайте же повторим успех вот

24:36

Speaker A

этот вот давний, а, и напишем тоже эту программу, которая выводит Hello World на экран. Для этого нам нужно для начала добавить себе ящик с инструментами. То есть вот как работник склада, работник там завода идёт на смену, он берёт с

24:52

Speaker A

собой какой-то ящик с инструментами. И в зависимости от того, какая конкретно перед ним стоит задача, такой ящик с инструментами этот работник и берёт для себя. В языках программирования абсолютно то же самое. Конкретно в GOL мы хотим вывести текст на экран. Для

25:08

Speaker A

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

25:27

Speaker A

инструментов FMT", нужно написать импорт до этого и потом в скобочках, в кавычках написать название ящика с инструментами FMT. Что мы вообще тут написали? Мы сказали, что возьми, пожалуйста, уважаемый Goldeng, ящик инструментов FMT, потому что он нам нужен. А для чего

25:46

Speaker A

он нам нужен, мы сейчас ему расскажем далее. То есть тут в третьей строчке мы просто говорим: "Пожалуйста, возьми ящик инструментов FMT". Сейчас он нам подсвечивает красным. Опять же преимущество редактора кода. Он нам просто говорит, что FMT мы взяли, то

25:59

Speaker A

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

26:12

Speaker A

написал, ты нигде этот ящик не используешь, но ты его зачем-то берёшь, как бы, да, себя перегружаешь. Ну зачем?

26:18

Speaker A

И он нам это просто подсказывает. Давайте же сейчас напишем, наконец-таки, воспользуемся этим ящиком. То есть, чтобы воспользоваться конкретным ящиком с инструментами, нужно написать его название. То есть, ну, мы с вами взяли ящик с инструментами FMT, так и пишем

26:33

Speaker A

FMT, чтобы взять конкретный инструмент из вот, то есть FMT - это целый ящик, условно говоря, да? Давайте обусловимся, что когда мы вот тут вот импортируем какой-то, это называется импорт пакета на опять же айтишном слнге, но пока мы это воспринимаем как взятие с собой

26:49

Speaker A

ящика с инструментами. То есть это целый ящик, там много разных инструментов всяких разных. Там и отвёртки, и пасатижи, и, может быть, какой-то насос, и что угодно. Но нам из этого всего ящика нужен конкретно один инструмент. В данном случае конкретно только

27:06

Speaker A

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

27:32

Speaker A

print ln. Что такое print ln? То есть с английского это как бы выведи на экран.

27:39

Speaker A

По сути, print - это выведен на экран. Ln мы чуть подальше разберём, что такое ln. Пока можно вот это всё воспринимать как отдельный инструмент, который выводит на экран текст. То есть мы с вами написали, что из ящика инструментов

27:53

Speaker A

FMT возьми, пожалуйста, инструмент printl. Но, как мы видим, опять нам редактор кода подсказывает, что какая-то тут ошибка, что мы что-то написали, но оно не запустится. Почему оно не запустится?

28:05

Speaker A

Потому что инструмент Printl, инструмент, который нам выводит на экран текст, что он от нас требует? Он от нас требует конкретный текст, который мы хотим вывести, потому что ему вот так вот непонятно, а что выводить-то надо?

28:18

Speaker A

Ну, типа FMT printl. О'кей. Язык программирования понял. Вот пока что всё, что язык программирования понимает, что он в главном пакете, что ему нужно взять ящик инструментов FMT, что начинать выполнение кода нужно конкретно вот с шестой строчки, да, потому что вот

28:33

Speaker A

это, ну, главный кусок кода, вот функция, кусок кода главный. И то есть вот этот код надо выполнить первым делом. А вот это он не понимает, ээ, что такое, потому что он не понимает, что ему на экран-то вывести. Он понял, что

28:45

Speaker A

типа ну ящик инструментов FMТ, из него мы берём инструмент, который вводит текст на экран.

28:51

Speaker A

А делаем-то мы что с этим инструментом? Ну что, что вывести на экран? Ему непонятно. Поэтому нужно ему это передать. Как это выглядит с точки зрения синтаксиса? Мы пишем круглые скобочки и в кавычках передаём ему текст Hello World. Всё. Вот, как мы видим, у

29:09

Speaker A

нас пропали всякие подчёркивания, всякие предупреждения. У нас, в принципе, корректно написанная программа. Давайте сохраним файл. Обязательно нужно файл сохранять. Смотрите, видите, если вот вот тут вот кружок такой чёрный, и он, ну, исчезает, когда я навожу, но так вот чёрный

29:25

Speaker A

кружок, это значит, что файл изменён и не сохранён. Обязательно нужно файлы сохранять. Для того, чтобы файл сохранить, нужно нажать вот сюда вот файл, save. Save. Оп, видим, чёрный кружок пропал, значит, файл сохранён.

29:41

Speaker A

Теперь давайте ещё раз сверху вниз пройдёмся по этой программе и посмотрим, что же тут вообще происходит. Мы с вами создали main.

29:49

Speaker A

Goфай. Что это значит? Main это значит, что файл у нас главный, что это самый главный файл в нашей программе. Точка go - это значит, что в файле содержится код на голенге. Конкретно код на голенге.

30:02

Speaker A

Никакой другой. Ни текст обычный, ни ещё что-нибудь. Там код на Джаве, нет. Код нанге. Main. Файл. Главный файл программы на Goeng. В этом главном файле мы говорим, что у нас главный пакет.

30:16

Speaker A

Опять же, что именно такое пакет, мы разберём далее. Что у нас главный пакет? Что нам нужно взять ящик инструментов FMT и что конкретно вот в этой функции, вот в этом куске кода у нас начинается выполнение. И первое и по сути

30:33

Speaker A

единственное, что мы делаем - это используем уже взятый ящик инструментов FMT, достаём оттуда инструмент print, который выводит нам на экран текст, и выводим на экран текст, который мы в него передали. Hello World. Давайте, наконец, запустим нашу первую программу.

30:51

Speaker A

Для этого нам необходимо нажать View или же V и тут нажать терминал. Вот он, терминал. Оп, у нас открывается терминал. можете написать ls для того, чтобы увидеть, что в вашей директории есть вот этот файл main GO. То есть

31:08

Speaker A

пишем опять же ls и нажимаем Enter. Оп, вот наш файл main. И вот он. Вот Stud. И мы как раз-таки в территории Studia.

31:19

Speaker A

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

31:35

Speaker A

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

31:49

Speaker A

программирования. И мы с вами язык программирования как раз-таки установили, когда настраивали окружение. Вот go веersionн может написать, увидеть, что у нас какая версия и скачана. Golengo. Так вот, опять напишу LS. Вот наш main Goфайл. И нам, чтобы запустить этот main go файл с помощью

32:05

Speaker A

языка программирования goeng, нужно написать в терминал go. Это значит, что мы обращаемся к языку программирования Goeng. Пробел. Пишем run. Это значит, что мы просим Goeng запустить какой-то файл. Но какой файл? Мы указываем третьим словом main.go. Go. Что тут

32:23

Speaker A

значит? Это значит, что мы просим язык программирования Goang запустить filma main. Нажимаем Enter. Бам. У нас в консоль выявился текст, который мы задали вот здесь. Вот.

32:36

Speaker A

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

32:51

Speaker A

давайте я тут напишу что-нибудь вообще, что угодно. Там AboboA, Roblox, Hello Moto. Сохраняем файл. Опять же не забываем сохранить. Пишу go run go. Нажимаю Enter. Вот. Abobo Roblox Hello Moto. То, что я пишу здесь, оно выводится на экран.

33:15

Speaker A

То есть опять же мы в главном пакете берём ящик инструментов FMT, который предназначен для того, чтобы выводить на экран. И в главной функции, в главном куске кода мы из этого ящика инструментов берём инструмент Printn, который просто выводит на экран строчку,

33:30

Speaker A

и передаём конкретную строчку, которую нужно вывести. То есть для работы со строками в языке программирования Goeng и в других языках программирования тоже используются кавычки. Для чего они нужны? чтобы язык программирования воспринимал написанный тут текст не как какой-то код, а просто как строчку,

33:50

Speaker A

чтобы он слова абоobба Roblox воспринимал не как ключевые слова языка программирования, как, например, Фун или как FMТ, а просто, чтобы это воспринималось как обычная строчка.

34:01

Speaker A

Поэтому нужно закрепить её в кавычки. И нам редактор кода просто вот подсказывает, что это строчка, потому что заключённая между скобочками, выделена красным, ну, выделено красным конкретно в моей теме, в вашей теме, там другим цветом может быть выделено, но

34:14

Speaker A

каким-то одним цветом. В скобочках это строчка. На самом деле в третьей строке FMT это тоже строчка, но так как она идёт после ключевого слова импорт, то язык программирования понимает, что ему нужно взять ящик с инструментами, который называется вот FMT. То есть мы с

34:30

Speaker A

вами можем посмотреть, какие ещё есть инструменты в ящике с инструментами FMT. Пишем FMT точка. И тут видите какие-то кучу непонятных инструментов. Вообще скан, print, какие-то с другими буквами, Fint, формат, RН, stringer, state. Это всё различные инструменты, которые лежат

34:51

Speaker A

в этом ящике с инструментами. Пока нам они не интересны, пока мы не будем заострять внимание на конкретно каждой функции, пока необходимо просто понять, что у нас есть ящик с инструментами FMT, и мы из него можем брать отдельный инструмент printlн. Давайте посмотрим на

35:06

Speaker A

ещё один инструмент, который лежит в ящике инструментов FMT, который тоже довольно часто используется. И он очень похож и внешне, и идеологически на то, что мы уже использовали на Printl, но называется чуть-чуть по-другому.

35:18

Speaker A

Называется он Print. Но опять же, если просто говорить, что дай мне инструмент, язык программирования такое не понимает, ему нужно сказать, из какого конкретно ящика с инструментами этот инструмент. Поэтому мы говорим FMT print, потому что print - это инструмент из ящика инструментов FMT

35:36

Speaker A

print. И точно также мы хотим передать ему какую-то строчку, потому что он очень похож на то, что мы с вами уже использовали на print ln, только print.

35:46

Speaker A

Сейчас как раз-таки вы поймёте, что такое ln и чем вот эти два инструмента отличаются. Давайте для наглядности я напишу вывод Hello World на экран три раза. Давайте посмотрим, что будет. Я пишу ещё раз FMT, Printl Hello world и ещё раз третий. Пишу FНT

36:07

Speaker A

PrintLN Hello World. Три раза вот написал. Сохраняю программу, захожу опять в терминал и запускаю её.

36:17

Speaker A

Вот вижу, у меня три раза Hello World вывелось, да? То есть каждый раз Hello World выводился с новой строчки. А теперь давайте посмотрим, что будет, если мы использовать будем инструмент не Print LM, а Print, который по сути своей

36:33

Speaker A

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

36:47

Speaker A

FMT Print. Видите, нам редактор кода предлагает много инструментов, которые лежат в ящике инструментов FMT, в том числе print, print f, println, fpint. Их довольно много. Сейчас нас интересует инструмент print. Есть он инструмент print ln, который мы уже разобрали, что

37:05

Speaker A

делает. Выводит на экран строчку и переводит курсор на новую строку. Давайте посмотрим, что делает инструмент просто print. И точно также выведем три раза Hello [аплодисменты] World. Старый код я сотру. Сохраняю файл и запускаю программу. Опа. Что мы видим? Мы видим,

37:41

Speaker A

что все наши три вывода Hello World были не с новой строки, как раньше, а они все в одну строчку вывелись. Почему? Потому что инструмент print, он просто выводит на экран строчку, которую мы с вами ему передаём, и всё. А инструмент printl он

38:00

Speaker A

выводит на экран строчку, которую мы ему передаём, но при этом перекидывает ещё курсор на новую строчку, из-за чего у нас каждый вывод с новой строки. Если мы используем print ln, давайте ещё раз запущу. Видите, используем print ln. То

38:16

Speaker A

есть ln - это как бы line, то есть на новую линию переведи курсор, напечатай на экран строку, которую я тебе передам, и после этого переведи курсор на новую строку. Всё. Вот поэтому мы с вами получаем каждый раз вывод с новой

38:29

Speaker A

строки. Вывели Hello World, перенесли курсор на новую строку. Вывели Hello World, перенесли курсор на новую строку и опять выводим Hello World и опять переносим курсор на новую строку. В случае же, когда мы используем просто print, у нас курсор на новую строку не

38:43

Speaker A

переносится. Что мы с вами получаем? Мы получаем, что вывод у нас весь на одной строке. Но вот в том, что сейчас вы видите, в этом выводе могут быть некоторые отличия в зависимости от того, какая у вас операционная система,

38:59

Speaker A

какой у вас терминал. Давайте посмотрим, что произойдёт в терминале ZS. Видите, вот здесь вот подсвечивается, что у вас за терминал ZSH. ZSH - это стандартный терминал для MacOS. Давайте посмотрим ещё раз, сделаем вывод вот этой программы, где просто три раза

39:13

Speaker A

использовали print. Мы видим, весь вывод у нас в одну строку, но в конце всё равно был перенос на новую строчку и какой-то странный процент. Что это значит? Вообще-то переноса на новую строку быть не должно, потому что мы его нигде не указывали в

39:28

Speaker A

нашей программе. Но терминал ЗС достаточно умный, чтобы отслеживать такие моменты, когда у нас в конце вывода программы нету переноса на новую строку, и он сам добавляет этот перенос и при этом пишет какой-то вот этот странный процент, что означает, что он,

39:43

Speaker A

этот терминал ЗS, сам добавил нам перенос на новую строку, хотя в программе его не было. Просто для того, чтобы мы взаимодействие с терминалом начали опять с новой строки и всё было довольно хорошо. Но есть другой у нас терминал, который очень часто

39:58

Speaker A

используется как стандартный терминал на многих дистрибутивах Linux, в том числе на Убунту. Это баш. Чтобы создать баштерминал, ну вот, в частности, на тут вот есть плюсик, есть стрелочка справа, и тут можно нажать баш. Вот давайте теперь вот в баше. Тут те же самые

40:15

Speaker A

команды доступны. Давайте теперь в баше мы запустим нашу программу. И то есть на Линуксе вы будете видеть, скорее всего, именно такой вывод, который вы сейчас увидите. Опа. Hello world. Hello world.

40:29

Speaker A

Hello world. Но переноса на новую строчку в конце не было. И мы продолжили после завершения программы работу с терминалом в той же строчке, в которой у нас был вывод программы, которую мы с вами написали. Почему? Да, потому что

40:42

Speaker A

так и должно отрабатывать приложение вместе с терминалом, если терминал не отслеживает того, что в конце вывода программы не было переноса на новую строку. И поэтому мы получили, в принципе, такой вот вывод. Поэтому, если вы на Linux, если вы используете баш,

40:59

Speaker A

то, скорее всего, будет у вас вот такой вот вывод. На maos у вас будет вывод, ну, ещё раз давайте посмотрим, следующего характера, что будет перенос на новую строку, но почему-то вот процент в конце будет, да, который сигнализирует нам о том, что терминал

41:14

Speaker A

ZSH сам увидел, что у нас нету этого переноса в конце программы. И чтобы не получать вот такую некрасивую штуку, ZS просто сделал сам перенос на новую строку. Давайте посмотрим, как это всё будет выглядеть на винде. Вот мы сейчас

41:27

Speaker A

с вами на винде. Та же самая наша программа. А мы зашли в терминал, то есть опять же вид нулеw и тут терминал.

41:36

Speaker A

А по умолчанию вызывается PowerShell. Также у вас может быть какой-нибудь другой терминал, например, вот этот Command Prompt, но вот на последних версиях Windows уже по умолчанию везде PowerSell используется. И запускаем нашу программу. Как мы видим, у нас все

41:52

Speaker A

принты вывелись в одну строчку. И в конце точно так же, как на Макоэсе, как на ЗСШе, был автоматический перенос на новую строку, хотя мы его не указывали.

42:03

Speaker A

Ну, то есть терминал PowerShell, стандартный терминал Windows, он точно также автоматически смотрит за тем, чтобы в конце всей программы был перенос на новую строку, чтобы мы не получили такой некрасивый вывод, как был в баше.

42:16

Speaker A

Если этого самого переноса нет, то Powerell сам делает этот перенос. Но в отличие от ЗСШа, тут никакого процента нету. То есть мы даже не можем узнать, это мы написали в конце перенос или это терминал сам за нас сделал перенос. Ну,

42:31

Speaker A

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

42:46

Speaker A

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

43:02

Speaker A

обсуждать программирование в вакууме, совсем уж обсуждать программирование в отрыве от компьютера - это довольно глупо. Компьютер у нас начинается с розетки. То есть в розетку нам приходит какое-то электричество, и компьютер, вся система компьютера питается от этого электричества из розетки. То есть тут

43:18

Speaker A

довольно всё просто. Первым делом ток из розетки попадает в блок питания. То есть почему не сразу напрямую в компьютер?

43:24

Speaker A

Почему через блок питания? Потому что ток в розетке довольно хаотичен. А он может в одну миллисекунду иметь одни параметры, там по частоте, по напряжению, в другую миллисекунду немножко другие. А компьютеру нужен конкретный, чёткий ток, который задан производителям. Блок питания преобразует

43:45

Speaker A

хаотичный ток из розетки, который нам приходит, хаотичный ток из розетки в конкретный ток, который нужен компьютеру. Поэтому у нас есть для этого блок питания. Далее от блока питания у нас питается материнская плата. И как мы видим, все остальные компоненты

44:01

Speaker A

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

44:22

Speaker A

общается через материнскую плату. Поэтому, собственно, эта плата и называется материнская. То есть она в себе как бы принимает все компоненты компьютера, и они через эту плату общаются. Значит, зачем нам нужен каждый отдельный компонент? Ну, давайте вот начнём с видеокарты. То есть видеокарта

44:36

Speaker A

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

44:52

Speaker A

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

45:04

Speaker A

Процессор - это вычисление, полное управление компьютером. То есть благодаря тому, что процессор умеет считать, он умеет туда-сюда кидать разные циферки, он умеет над ними производить операции логические и арифметические. Благодаря этому процессор управляет компьютером. Чуть попозже объясню, как именно он это

45:21

Speaker A

делает. Далее у нас есть жёсткий диск. На жёстком диске у нас самое первое, самое важное, что хранится - это файлы операционной системы. То есть, когда вы устанавливаете винду, например, или когда вы покупаете компьютер, где уже установлена винда или любая другая

45:36

Speaker A

операционная система, это операционная система, все её файлы, они хранятся на жёстком диске. В чём вообще плюсы жёсткого диска? Во-первых, в том, что он относительно дешёвый. То есть, например, купить 1 ТБ жёсткого диска - это гораздо дешевле, чем купить 1 ТБ оперативной

45:51

Speaker A

памяти. То есть можете, условно говоря, там в DNS зайти или какой-нибудь другой дистрибьютор электроники и посмотреть вообще, сколько будет стоить 1 ТБ жёсткого диска и 1 ТБ оперативной памяти. То есть жёсткий диск, он на порядок дешевле. Это во-первых.

46:03

Speaker A

Во-вторых, одно из самых главных преимуществ жёсткого диска в том, что он может хранить на себе информацию даже если в системе нет питания. То есть, что это значит? Один раз мы с вами установили винду на жёсткий диск. Далее мы компьютер можем выключить. Мы можем

46:18

Speaker A

его перевести вообще в другую квартиру. Мы можем поставить его в другой угол комнаты. Он может у нас стоять вообще месяцами выключенный. И потом вы включите компьютер и информация, которая сохранена на жёстком диске, она будет доступна. С ней будет всё в порядке,

46:34

Speaker A

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

46:50

Speaker A

диске. На жёстком диске хранятся все ваши программы, которые вы устанавливаете. Там скачиваете, например, там Counter Strike, да, там 100 ГБ. Это всё на жёстком диске сохраняется, чтобы когда вы компьютер выключили, когда вы компьютер перезагрузили, то все файлы, которые вы

47:03

Speaker A

скачали, они остались на компьютере и никуда не исчезли. Но зачем нам тогда вообще оперативная память? Казалось бы, типа какая-то странная хрень вообще. У нас все игры, вообще операционная система, всё хранится на жёстком диске, но у нас вот, ну, почему-то есть ещё

47:16

Speaker A

оперативная память. Так вот, один из просто самых больших минусов жёсткого диска в том, что он чертовски медленный.

47:26

Speaker A

Он прямо очень медленный. И поэтому современные операционные системы просто не могут находиться на жёстком диске в тот момент, когда мы с ними взаимодействуем. Что это значит?

47:38

Speaker A

Допустим, вы каким-то устройством периферии, допустим, мышкой начинаете двигать, да? Вот двигается курсор. То есть вы двигаете мышку. Информация о том, что вы двигаете мышку, она идёт в материнскую плату. Материнская плата сообщает эту информацию процессору, и процессор понимает, что кто-то, ну, юзер

47:55

Speaker A

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

48:12

Speaker A

того, чтобы сказать: "Слушай, малышка, вот пользователь двигает курсор, я посчитал, куда этот курсор нужно переместить. Вот перемести вот в это место". Ну вот, допустим, отсюда там сюда, да? Вот. Бам.

48:23

Speaker A

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

48:41

Speaker A

найдёт их, потому что жёсткий диск, он очень большой, там может быть несколько терабайт. Вообще это представьте, как вот просто в стоги сена иголку найти.

48:48

Speaker A

нашёл вот эти файлы операционной системы, повзаимодействовал с ними, сказал, что курсор надо пододвинуть, жёсткий диск, там свои эти пластины там, да, что-то пододвинул, как-то там поменял, нашёл нужную инфу, отдал. Это всё очень долго, просто капец. И поэтому даже простейшие операции с операционной

49:06

Speaker A

системой современной были бы очень затруднительны. Всё бы просто лагало, тупило, было бы очень долгим. Как это решается? Это проблема. Части операционной системы, которые нужны для работы вот в данный момент, в данную секунду, они процессором заранее с жёсткого диска выгружаются в оперативную

49:27

Speaker A

память. Ну, буквально копируются. Зачем? Почему в оперативную память? Потому что оперативная память очень быстрая в сравнении с жёстким диском, даже в сравнении с SSD. Оперативная память - это просто пушка. Она очень быстрая, она в несколько раз быстрее. И это позволяет

49:45

Speaker A

нам сильно ускорить взаимодействие с компьютером. Каким образом? Компьютер включается. Вот вы нажимаете кнопку включения, идёт питание на материнскую плату. Материнская плата проверяет, что в принципе все компоненты в компьютере находятся, что компьютер можно запускать. И отдаёт материнская плата команда процессору, типа давай валяй,

50:02

Speaker A

короче, загружай операционную систему, потому что первым делом в компьютере, упрощённо говоря, очень упрощённо говоря, загружается операционная система. Процессор понимает, что он заколебётся бегать на жёсткий диск каждый раз, когда нужно какое-то произвести взаимодействие с операционной системой. Почему заколебётся? Потому

50:19

Speaker A

что, опять же, жёсткий диск очень большой. Это как искать иголку в стуге сена. Жёсткий диск очень медленный. Даже когда ты эту самую иголку найдёшь, ты будешь очень медленно с ней взаимодействовать, она будет очень медленно отвечать. процессор всё это

50:30

Speaker A

понимает, и он файлы операционной системы, которые необходимы для работы, вот в данный момент он их берёт процессор, и копирует жёсткого диска медленного просто вот с этого слона, с этого мамонта копирует их в оперативную память. То есть вот нарисовал условное

50:46

Speaker A

бы значения жёсткого диска. То есть у нас вот есть жёсткий диск, на какой-то части этого жёсткого диска вот хранится операционная система, да, занимая довольно значительную часть.

50:55

Speaker A

Допустим, мы там ещё с вами скачали Counter Strike, да, там ещё какая-то часть жёсткого диска у нас занята Counterстрайком и ещё какая-то часть жёсткого диска - это вот наш браузер. Ну и, собственно, давайте вот заново ещё раз это всё прогоним. То есть мы

51:07

Speaker A

нажимаем кнопку включения, блок питания начинает подавать питание на материнскую плату. Материнская плата оживает, она проверяет сначала все компоненты компьютера, что они в принципе на месте и что мы можем запускать компьютер.

51:19

Speaker A

Потом он даёт управление процессору. И процессор у нас, понимая, он сразу понимает, что типа если операционная система останется на жёстком диске и он будет работать с операционной системой, которая находится на жёстком диске, то он просто заколебётся. Это слишком долго

51:35

Speaker A

будет ему даже простейшие движение мышки обрабатывать. Вот мышку пододвинули, пришёл сигнал о том, что мышку пододвинули материнскую плату.

51:44

Speaker A

Материнская плата передала этот сигнал процессору. процессор такой, а кто-то пододвинул мышку и начинает идти на жёсткий диск. На жёстком диске искать операционную систему. Это уже долго, потому что, опять, видите, тут несколько пластинок, несколько жёстких дисков, в принципе, может быть. Короче, он нашёл

52:01

Speaker A

операционную систему. Во всей этой огроменной операционной системе он нашёл какой-то файл, который нужен конкретно для того, чтобы там двигать мышку. Он обратился к этому файлу. Это всё очень долго. сам процесс обращения идёт очень долго, и в итоге мышка бы у нас просто двигалась очень

52:19

Speaker A

медленно, всё бы жёстко лагало. И это просто движение мышкой. А теперь представьте, если бы мы производили какие-то более сложные операции, там открыть браузер, например, или там что-нибудь посчитать, там скопировать какие-то файлы, это всё очень долго, просто очень долго. И процессор, это всё

52:37

Speaker A

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

52:59

Speaker A

операционной системы, то есть необходимые в данный момент для работы с операционной системой файлы в оперативную память. То есть берёт буквально вот так вот часть операционной системы, копирует её в оперативную память. Вот она у нас тут теперь начинает располагаться. Что это даёт

53:15

Speaker A

компьютеру? Компьютеру это даёт то, что теперь, когда мы, например, двигаем ту же мышку, опять этот сигнал идёт в материнскую плату. материнская плата отдаёт этот сигнал процессору, и процессор понимает, что ему теперь не нужно на огроменном, медленном, жёстком диске искать нужные файлы, там, вот

53:31

Speaker A

взаимодействовать с ними. Он понимает, что все нужные файлы, они находятся в оперативной памяти. Он понимает, где конкретно они находятся. И он знает, что взаимодействие с этими файлами будет очень быстрым. То есть он очень быстро обратится в а оперативную память, найдёт

53:45

Speaker A

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

53:57

Speaker A

оперативной памяти? Зачем нам вообще жёсткий диск? Как бы, да, давайте просто оперативной памяти напихаем там и всё.

54:03

Speaker A

Но у оперативной памяти есть один огромный минус, который, с одной стороны позволяет ей быть очень быстрой, но с другой стороны, из-за этих же самых конструктивных особенностей, которые позволяют оперативной памяти быть в несколько раз быстрее жёсткого диска, из-за этих же конструктивных

54:17

Speaker A

особенностей оперативная память не может хранить информацию, если на ней нет питания. Что это значит? Это значит, что если мы с вами что-то записали в оперативную память, а потом выключили компьютер, то все данные автоматически теряются. То есть как только мы с вами

54:35

Speaker A

выключаем компьютер, в оперативной памяти все данные просто стираются. Всё, нету никак. И никак их не сохранить, потому что оперативной памяти для поддержания информации, которую мы в неё записали, постоянно необходимо напряжение, постоянно необходим какой-то ток. А если мы компьютер из розетки

54:51

Speaker A

выключим? А если просто мы компьютер выключим, например, и захотим почистить там, да, отключим блок питания, всё, всё будет затёрто. Мы этого себе позволить не можем, потому что мы не хотим каждый раз при включении компьютера переустанавливать операционную систему, да, и каждый раз при выключении терять

55:09

Speaker A

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

55:25

Speaker A

ноутбуках, и там в умных телевизорах, в умных колонках. Вообще вот сейчас очень-очень много где. Файлы, которые нам необходимо хранить долго, мы храним на жёстком диске. То есть какое-то продолжительное время файлы нам нужно хранить. Видеофайлы или там файлы операционной системы или файлы игры. Это

55:43

Speaker A

всё нам нужно хранить долго. Мы хотим это хранить, даже если компьютер перезапускается. И мы поэтому выбираем для этих целей жёсткий диск, который отлично подходит. Но у жёсткого диска есть минусы, то, что он очень медленный и очень огромный. И поэтому с ним

55:56

Speaker A

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

56:11

Speaker A

того, чтобы работать с компьютером в данную секунду. Эти файлы выгружаются в оперативную память, которая гораздо быстрее жёсткого диска, и у нас обеспечивается с вами моментальное взаимодействие с компьютером. Очень быстрое, но из минусов мы не можем в этой оперативной памяти хранить вечно.

56:26

Speaker A

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

56:40

Speaker A

похраниться в оперативной памяти, но рано или поздно она оттуда будет удалена. Либо когда компьютер выключится, либо когда мы сами с вами закроем какую-нибудь вкладку. Как вы видите, на жёстком диске у нас хранится не только операционная система, но ещё и

56:53

Speaker A

браузер, и какие-то игры, и, возможно, какие-то фильмы. Что вообще происходит, когда мы с вами запускаем браузер? По сути, с браузером во время его запуска происходит то же самое, что происходит с операционной системой во время запуска компьютера. Файлы браузера, которые

57:08

Speaker A

необходимы для работы с ним в данный момент, они процессором берут и выгружаются в оперативную память. Зачем?

57:16

Speaker A

По абсолютно тем же самым причинам, почему операционная система выгружается в оперативную память. Потому что работать с браузером, когда он хранится полностью на жёстком диске, и ходить на этот жёсткий диск - это очень долго.

57:28

Speaker A

Обычно открытие вкладки занимало бы несколько секунд, если не минут, в зависимости от того, насколько быстрый жёсткий диск. Это просто непозволительно. Пользоваться компьютером было бы невозможно. Поэтому данные браузера, которые необходимы в данный момент, берутся и когда вы браузер запускаете, переносятся в

57:47

Speaker A

оперативную память. То есть вот я так же, как операционную систему, примерно нарисовал браузер в оперативной памяти.

57:52

Speaker A

Опять же, обозначения очень условные. Вот мы с вами мышкой наводим на иконку браузера. Процессор понимает, что мышка сейчас на иконке браузера. Мы нажимаем левую кнопку мыши. Все эти команды идут в материнскую плату, отдаются процессору. Процессор всё понимает, где

58:08

Speaker A

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

58:21

Speaker A

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

58:35

Speaker A

система, и поэтому он как бы меньше оперативной памяти занимает, потому что, в принципе, браузер, он сильно проще, чем операционная система, ему не нужно так много памяти. Вот. И опять же мы получаем все преимущества оперативной памяти. У нас максимально быстрое

58:49

Speaker A

взаимодействие с браузером происходит. Нам не нужно ждать долгий жёсткий диск, и всё круто, все рады. Но важно понимать, что выгрузка программы в оперативную память, она не только для браузера, не только для операционной системы. В принципе, любая программа, абсолютно любая, которую вы запускаете у

59:11

Speaker A

себя на компьютере, она с жёсткого диска выгружается в оперативную память. Почему? всё те же самые причины.

59:20

Speaker A

Неважно, это браузер, неважно это Counter Strike, неважно, это любая другая игра или написанная вами же программа своими же руками, неважно.

59:31

Speaker A

Процессор понимает, что на жёстком диске, если всё это будет в реальном времени обрабатываться, это будет очень долго. Поэтому он любую вообще программу, любую игру, даже если вы сами написали эту игру, даже если вы сами написали эту программу и запускаете

59:50

Speaker A

файлы с кодом, то процессор перед тем, как, собственно, запустить программу или игру, он переносит её файлы, которые необходимы для работы в данную секунду с ней, в оперативную память, да? То есть, например, даже вот возьмём операционную систему, не сразу же вся операционная

60:09

Speaker A

система в оперативную память переносится, потому что никакой оперативной памяти не хватит. Если посмотреть там сколько винда весит, она там гигабт 70 весит. То есть у нас нету 70 Гб оперативной памяти, но переносятся данные, которые нужны в данный момент,

60:25

Speaker A

то есть в данную секунду, которые файлы нужны, они переносятся в оперативную память. Благодаря этому у нас и оперативная память не перегружается, и мы получаем все преимущества работы с оперативной памятью. У нас ускоряется работа компьютера, и, в принципе, она

60:39

Speaker A

становится возможно полноценной нормальной, адекватная работа с компьютером. Примерно так можно максимально поверхностно писать работу компьютера. То есть ещё раз всё вместе.

60:48

Speaker A

У нас есть розетка, к розетке подключен блок питания. И в момент, когда мы нажимаем кнопку включения, питание с блока питания идёт на материнскую плату.

60:58

Speaker A

Мастеринская плата сначала проверяет, что все компоненты компьютера подключены, что к ним есть доступ и потом отдаёт управление процессору.

61:06

Speaker A

Процессор, понимая, что сейчас будет работа с операционной системой, часть её файлов выгружает в оперативную память.

61:12

Speaker A

Для чего? Для того, чтобы быстро можно было работать с операционной системой. И юзер там не офигевал, почему так долго.

61:19

Speaker A

У меня просто курсор мышки двигается по экрану. Процессор выгружает часть данных операционной системы в оперативную память. Компьютер запускается. Всё.

61:27

Speaker A

Теперь, когда вы двигаете мышкой, когда вы нажимаете какие-то клавиши, всё это идёт в материнскую плату и отдаётся потом на откуп процессору. И процессор уже думает, что делать с этой информацией. Что делать с той информацией, что вы пододвинули мышкой?

61:39

Speaker A

Ну, например, нужно отдать команду операционной системе, что подвинь на экране курсор там на 10 см вправо или там на 50 см вниз, там есть какой-то очень большой экран. Всё это как бы думает, просчитывает процессор. Потом вы наводите курсором на браузер, нажимаете

61:55

Speaker A

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

62:10

Speaker A

поработали с браузером, закрываем браузер, нажимаем там этот красный крестик. Всё, процессор понимает, что работа с браузером прекращена, и можно браузер убрать из оперативной памяти. Он берёт его и убирает из оперативной памяти. Почему он убирает его из оперативной памяти? Да потому что он в

62:27

Speaker A

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

62:40

Speaker A

перезагрузится, всё. То есть осталась там операционная система только в оперативной памяти. Допустим, захотели открыть Кэску. Ну, понятное дело, там часть данных Кэски, она тоже перенесётся на какие-нибудь слоты оперативной памяти. И так, собственно, по кругу.

62:54

Speaker A

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

63:11

Speaker A

памяти, потому что они так и так бы там стёрли за несколько секунд. И выключает компьютер. Всё, у нас все данные, которые необходимо было сохранить, сохранились на жёстком диске.

63:21

Speaker A

Оперативная память очищена и компьютер выключен. Ну и потом, собственно, когда мы будем компьютер включать, я уже думаю, вы поняли, что будет происходить.

63:30

Speaker A

пойдёт питание на материнскую плату, процессор выгрузит операционную систему, а точнее только её необходимую часть в оперативную память, и пойдёт дальше работа там с разными программами. Нас как разработчиков, а go - это преимущество эээнд разработка, то есть можно сказать, что нас как ээкэнд

63:47

Speaker A

разработчиков наиболее интересуют следующие части компьютера. Это процессор, потому что процессор будет нам компилировать и запускать наши программки. Это жёсткий диск, потому что файлы с кодом будут храниться на жёстком диске. И это оперативная память, потому что любая программа, будь то браузер,

64:05

Speaker A

будь то игра, или будь то программа, которую мы с вами написали своими руками, она в момент запуска загружается в оперативную память. То есть когда мы её просто написали, да, там собрали нашу программку, она просто лежит у нас на

64:21

Speaker A

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

64:39

Speaker A

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

64:57

Speaker A

компьютера и процесс запуска программ. Это поверхностное знание поможет нам очень сильно в дальнейшем понять вообще, что происходит, когда мы с вами пишем [музыка] код. Теперь возвращаемся от теории устройства компьютера к нашему языку программирования. На повестке дня у нас

65:17

Speaker A

тема переменные. То есть это, как вы могли понять, векторное изображение оперативной памяти. Сейчас поймёте, что к чему. В общем, у нас сейчас тема переменная. Я думаю, многие из вас знают вообще, что такое Flapy Bird. То есть давайте посмотрим, если вдруг кто не

65:33

Speaker A

знает. То есть Flppy Bir - это игра, это кликер. Мы кликаем по экрану, и у нас летает такая вот птичка и пролетают трубы. То есть каждую трубу, которая она пролетает, эта труба засчитывается ей в общий счёт. Чем больше мы набрали с вами

65:47

Speaker A

очков, тем лучше. То есть каждая труба плюс счёт. Вот проехали 10, 11, 12, пролетели, 13 пролетели 14 и так далее. У нас есть некоторый счёт, который нам подсказывает, сколько мы уже труп пролетели и как много очков набрали. То есть вот три очка, четыре

66:10

Speaker A

очка. Кто-то скажет: "Очко может быть только одно". Но сегодня у нас немножко более серьёзная тема, поэтому мы пять очков набрали, шесть, семь, ну и так далее. То есть есть некоторый счётчик, который подсказывает, сколько у нас сейчас очков, и он увеличивается каждый раз на

66:31

Speaker A

один + о + 1, 9 10. И мы в любой момент, даже если мы сбились со счёта и забыли, сколько мы там с вами этих труб пролетели, мы можем посмотреть на этот счёт и увидеть то, что у нас там число

66:44

Speaker A

10 или у нас там число 11 и так далее. Как вообще это выглядит с точки зрения программы? Как это выглядит с точки зрения компьютера?

66:56

Speaker A

Хранение вот такого вот числа, то есть хранение нашего счёта 11, 12, да, 13 14.

67:04

Speaker A

15. То есть как с точки зрения компьютера выглядит хранение вот этого числа? То есть напоминаю, каждый раз, когда мы запускаем любую программу, любую игру, неважно, скачанная из интернета, написанная нами самими или ещё откуда-то, любая программа или любая игра во время запуска полностью или

67:23

Speaker A

частично выгружается в оперативную память. Даже когда мы с вами запускаем Flappy Birds, неважно на компьютере или на телефоне, на телефоне примерно такое же устройство памяти, мы запускаем нашу игру, она выгружается в оперативную память. То есть давайте это проиллюстрируем. А мы вот запускаем

67:42

Speaker A

Flppy Birds. У нас открывается Flopy Birds. Это значит, что какая-то часть оперативной памяти будет занята этой игрой. То есть опять же, отсылаясь к предыдущему уроку, мы с вами запускаем программу. эта программа или игра выгружается в оперативную память. Для

67:58

Speaker A

чего? Для того, чтобы максимально быстро с ней взаимодействовать. То есть в случае с Лопибрсом выгрузка игры в оперативную память нужна для того, чтобы каждый раз, когда мы нажимаем на экран, эти касания регистрировались практически моментально, чтобы у нас не было

68:13

Speaker A

каких-то лютых лагов, в принципе, чтобы в игру было можно играть. Вот мы запустили Flppy Birds. Эта игра у нас вот была загружена в оперативную память.

68:22

Speaker A

То есть то, что я обвёл красным. Можно условно считать, что вот эти вот слоты оперативной памяти, это у нас зарезервировано под игру Flappy Birds, и она там и находится, эта игра, благодаря чему процессор максимально быстро может взаимодействовать с игрой Flppy Birds, и

68:38

Speaker A

касание, которое мы производим с телефоном или нажатие мышки, если мы играем на компьютере во Flappy Birds, чтобы они максимально быстро регистрировались в процессоре и чтобы максимально быстро процессор, что самое главное, мог влиять на игру, зная, что пользователь нажал на кнопку. То есть

68:55

Speaker A

пользователь нажал на кнопку, и процессор, благодаря тому, что игра в оперативной памяти, моментально может влиять на игру и моментально может подкидывать нашу птичку. То есть, если бы это всё было на жёстком диске, если бы у нас Flppyбрс так и оставался на

69:08

Speaker A

жёстком диске, как он хранится там постоянно, когда мы просто скачали игру, это всё было бы очень долго. Ну, я думаю, вы уже из предыдущего урока это поняли. Так вот, запускаем Flopy Birds.

69:19

Speaker A

У нас Flppy Bir Birds выгружается в оперативную память, но мы ещё хотим хранить наш счёт 4 5ше. Мы хотим запоминать этот счёт и хранить его. Так как у нас вся игра по сути выгружена в оперативную память, то вот этот вот счёт

69:37

Speaker A

6 7 8 это тоже часть игры, это тоже часть оперативной памяти. И эта циферка 89, она хранится просто на каком-то отдельном слоте оперативной памяти внутри нашей игры. То есть вот, допустим, вот в этом самом первом. Что это значит? Мы пролетели первую трубу,

69:59

Speaker A

вторую трубу и по сути вот эта циферка - это часть игры. То есть в данном случае у нас игра сейчас выгружена в оперативную память, поэтому эта циферка - это как бы ну часть оперативной памяти тоже внутри игры. Давайте нарисую. Вот

70:11

Speaker A

буквально у нас тут цифра три. Она прямо в оперативной памяти хранится. Вот натурально так это и выглядит. То есть вот у нас с вами вся игра выгружена в оперативную память. Мы начинаем лететь.

70:22

Speaker A

У нас ноль изначально, да? Давайте вот изначально напишу ноль. Поехали. Один. Всё, мы пролетели эту трубу. Процессор понял, что мы пролетели трубу и записывает в игру один. Дальше мы летим. Два. Процессор понял, что мы пролетели два. и записывает в игру два. Ну, а так как

70:43

Speaker A

игра у нас выгружена в оперативную память, то пишем как бы это в слот оперативной памяти. Дальше вот мы летим три, ну, и, соответственно, три. И так дальше. То есть, что вообще сейчас происходит? У нас игра выгружена в оперативную память. У нас есть счёт,

71:00

Speaker A

который подсказывает, сколько мы в данный момент пролетели труб. Четыре. Вот пять пролетели, да? Тут циферка пять. По сути, вот эта область памяти, которая у нас хранит какое-то число и с которой мы можем взаимодействовать, то есть мы можем прочитать это число, да,

71:16

Speaker A

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

71:30

Speaker A

есть было пять, стало шесть. По сути, вот эта вот область памяти, которая представляет из себя какое-то число - это переменное. То есть это и есть переменная. То есть почему даже название такое переменное? Потому что какая-то область памяти, которую мы можем менять,

71:46

Speaker A

да? То есть у нас вот сейчас шесть, теперь семь. Оп, взяли семь, написали. Дальше полетели восемь, оп, взяли восемь написали. То есть вот эта вот область памяти, где хранится какая-то циферка, это и есть переменная.

72:03

Speaker A

Всё. То есть просто переменная, это какая-то область в памяти, где мы с вами храним какое-то значение, с которым мы можем взаимодействовать, да? То есть дальше полетели девять. Вот девять это переменная. Давайте сейчас посмотрим, как это выглядит внутри языка

72:21

Speaker A

программирования. Возвращаемся в наш редактор кода. Опять нажимаю плюсик и пишу main. То есть главный файл в главном пакете. Опять же, что такое пакет, мы разберём с вами чуть далее, когда будем писать более сложные программы. Главная функция, то есть

72:37

Speaker A

главный кусок кода. Всё, по сути, можем теперь начинать писать наш код. Давайте с вами, а, по аналогии с Флапи Бёрсом.

72:46

Speaker A

То есть тут у нас есть Flopy Birds, у нас какая-то переменная, какая-то циферка, да, которая считает наш счёт.

72:52

Speaker A

То есть счёт по-английски - это скор. Давайте вот просто создадим переменную скор в нашем коде. То есть я сейчас напишу, а потом объясню, что я написал. То есть что тут сейчас у нас произошло? Я создал переменную с именем

73:07

Speaker A

score, которая равна нулю. Что это значит? что я зарезервировал какую-то область памяти, какую именно это нас не интересует, потому что компьютер, язык программирования, операционная система, все они вместе за нас позаботятся, чтобы в оперативной памяти найти нужную ячейку, которая лучше всего подойдёт. То

73:28

Speaker A

есть я просто какую-то рандомную ячейку беру, резервирую её, называю её скор, то есть счёт, и кладу туда циферку ноль.

73:39

Speaker A

Как это выглядит вообще в компьютере? То есть я беру там вот в своей уже программе, да, которую я пишу, вот написанная мной программка, да, вот я её синим цветом обозначил. В ней я просто беру какую-то ячейку памяти, вообще

73:52

Speaker A

любую. Компьютер сам выберет, какую именно. Называю её Score. Вот, называю её Score и кладу туда нолик. Вот. То есть у меня есть моя какая-то программка. Я создаю там переменную в оперативной памяти, потому что, в принципе, у нас как бы программы,

74:09

Speaker A

да, они все запускаются в оперативной памяти. Все переменные, которые мы с вами создаём, они также создаются в оперативной памяти. А я эту переменную обозвал скор и положил туда нолик. То есть вот это вот двоеточее равно, это значит, что просто типа создай и положи

74:26

Speaker A

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

74:41

Speaker A

что мы тут какие-то символы там написали, от этого ничего не меняется, как бы ничего не запускается, ничего нигде не создаётся. Это просто файл с кодом. Но когда мы эту программу запустим, когда она выгрузится в оперативную память, то в момент, когда

74:56

Speaker A

язык программирования дойдёт до четвёртой строчки, он увидит, что ему нужно создать переменную скор со значением ноль, и он выделит отдельную ячейку памяти в оперативной памяти, назовёт её скор и положит туда нолик.

75:10

Speaker A

Вот что мы с вами написали. И помните, как мы с вами в предыдущем уроке выводили на экран Hello World, то есть по сути какую-то строчку или другие слова. Точно также мы можем выводить на экран значения переменных. То есть мы

75:24

Speaker A

сейчас можем вывести на экран нолик просто выведя на экран скор. Как это вообще выглядит? Сначала берём необходимый нам ящик с инструментами. То есть нам нужен для того, чтобы выводить на экран, нам нужен ящик инструментов FMT. Из этого ящика инструментов мы

75:41

Speaker A

берём инструмент printl, потому что я хочу, чтобы у меня был перенос на новую строку. И опять же можем вывести какой-то текст, но текст мы выводили в предыдущем уроке. Сейчас мы хотим вывести значение переменной. Для этого просто нужно написать название этой

75:57

Speaker A

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

76:15

Speaker A

Меня интересует мой файл main go. И я пишу go run go, то есть язык программирования Go. Пожалуйста, запусти программу, которая описана, код, который лежит в файле main Go. Enter. Опа, вывелся ноль. То есть, что вообще произошло в нашей программе? Мы сначала

76:34

Speaker A

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

76:49

Speaker A

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

77:04

Speaker A

И в компьютере берётся и создаётся какая-то переменная, выделяется память, да, берётся какая-то ячейка оперативной памяти, она называется Score, и в неё кладётся ноль. Вот что произошло в шестой строчке. В нашей программе, которая уже в оперативной памяти.

77:21

Speaker A

Дополнительно создалась переменная, дополнительно выделилась какая-то ячейка, она приобрела какое-то имя, и мы записали туда какое-то значение. Ну, в данном случае переменная score, в которую мы положили ноль. А потом мы вывели это на экран. То есть опять же где-то там у нас есть вот этот вот

77:41

Speaker A

инструмент, который выводит на экран. Этот инструмент понимает, что мы в него передали скор, то есть название. Что это даёт инструменту? Он по названию может найти нужную ячейку в памяти и вывести её значение. То есть мы говорим: "Выведи на экран

77:57

Speaker A

score." Этот инструмент printl, который выводит на экран, он ищет в нашей программе, внутри нашей программы переменную скор, ячейку памяти ср и выводит её значение, то есть ноль. Вот у нас что и произошло. У нас появился ноль. То есть для наглядности мы сюда

78:15

Speaker A

можем написать что угодно, там три единицы можем написать, да? Сохраняем файл. Пишу go, run, main, go. И у нас выявилось три единицы. То есть логика абсолютно такая же. Наша программа запускается, она выделяется в оперативную память копируется и потом

78:33

Speaker A

выполнение программы доходит до шестой строчки. И тут компьютер как бы вот в шестой строчке он понимает, что мы с помощью языка программирования от него требуем создать переменную с именем score и положить в неё три единицы. И наш компьютер это всё понимает. язык

78:49

Speaker A

программирования, понимает, что мы написали, и создаёт переменную, то есть сам выбирает какую-то ячейку памяти, называет её скор и кладёт в неё три единицы. Вот такая у нас картина на момент, когда мы выполнили вот эту вот строчку. Просто наша программа, в нашей

79:05

Speaker A

программе создалась переменная, то есть, да, какая-то область памяти, у этой области памяти какое-то название есть и значение там вот три единицы. Потом мы дошли до восьмой строки, взяли ящик с инструментами FMT, который нужен для того, чтобы, в принципе, там выводить на экран

79:20

Speaker A

поразному, да, любые значения. Взяли инструмент конкретный из этого ящика инструментов, который просто выводит на экран и в конце ещё переносит курсор на новую строчку и передаём в него переменную, то есть не текст, да, как мы там в предыдущий раз с вами делали там

79:36

Speaker A

какой-нибудь, а именно название переменной. Это позволяет нашему инструменту понять, что именно мы хотим вывести. Инструмент Printl видит, что мы передали в него переменную с именем Score. Он берёт, ищет в оперативной памяти нужную ячейку, которая называется Score, и берёт из неё значение 111. Ну

79:56

Speaker A

и, собственно, мы это видим на экране. Стоит сказать, что в Go доступны переменные не только целочисленного типа. целочисленный тип - это просто 1 2 3, 100, 50 и так далее. То есть это целые числа. Мы можем хранить в

80:12

Speaker A

переменных не только целые числа, но и дробные числа, например, там полтора или 3 или число пи, например. Также мы в переменнах можем хранить строки и другие типы данных, которые мы разберём далее.

80:27

Speaker A

Давайте сначала разберём простой пример. Вообще создадим дополнительные переменные. То есть, если перейти в игру нашу обратно, да, во Flappy Birds, то тут можно увидеть, что когда игрок проигрывает, то у него вылезает надпись Gameo Oover. То есть надпись Game Over,

80:44

Speaker A

по сути, это какое-то то же значение, которое процессор берёт, да, из нашей программы и выводит на экран. То есть где-то оно должно храниться, что конкретно мы выводим game over, а не там что-нибудь там game oper или вообще там

81:00

Speaker A

Hello World. То есть тут же выводится не Hello World, да, а Game Over. Где-то это сохранено значение. Мы можем в нашей микропрограммке тоже нечто подобное сымитировать и сохранить это значение в переменную. То есть тут Gameover, это можно назвать просто как текст. И

81:20

Speaker A

давайте создадим переменную, которую которая называется текст, и положим в неё значение game over. Я так и напишу текст. Опять же такой же синтаксис, двоеточие равно для создания переменной и для того, чтобы сразу же положить в неё значение. Текст двоеточие

81:38

Speaker A

равно game over. То, что он у нас подчёркивает красным, можно опять же преимущество редактора кода. Если что-то подчёркивается красным, значит, где-то ошибка. Мы наводим и нам пишет, почему у нас именно ошибка. То есть в данный момент описано, что мы создали

81:56

Speaker A

переменную, но нигде её не использовали. Почему вообще это считается в goeng ошибкой? Просто потому, что когда мы с вами создаём какую-то переменную, мы резервируем область памяти. То есть, если бы у нас, например, было там три переменных, да, и мы бы уже не влезали

82:14

Speaker A

как бы в текущий занимаемый программой объём. То есть вот у нас две переменные создано, а мы хотим ещё третью создать.

82:22

Speaker A

Её как бы уже, ну, некуда класть, эту третью переменную. Для этого программа начала бы занимать больше места, и тогда мы бы уже смогли положить туда новую переменную. Чем это плохо? Тем, что мы начинаем занимать очень много места. И

82:37

Speaker A

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

82:54

Speaker A

используем, то мы, по сути, просто выкидываем кусок оперативной памяти. Мы создали переменную, мы зарезервировали область памяти, да, заняли какую-то ячейку и ничего с этим не сделали. Зачем мы тогда резервировали эту область оперативной памяти? По сути, мы бы могли

83:13

Speaker A

такого же абсолютно результата выполнения программы добиться, если бы мы просто не создавали эту переменную и наша программа занимала бы меньше места.

83:22

Speaker A

Вот. То есть абсолютно то же самое. Нам не нужно вот эта вот лишняя оперативная память под вот эту переменную, потому что зачем? Мы просто её выделим в оперативной памяти и никак не используем. Поэтому нам говорит, что, братишка, давай-ка не будем

83:37

Speaker A

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

83:54

Speaker A

можем до скоро, да, вывести вот тут вот FMT printl и вот текст. Сохраняю файл.

84:02

Speaker A

Перехожу опять в терминал и пишу go run go. Запускаю. И что мы видим? Мы сначала вывели переменную текст, да? Вот смотрим, девятая строчка. Мы выводим переменную текст. В переменный текст хранится значение game over. Вывели game over. Потом выводим переменную score. В

84:22

Speaker A

переменной скор хранится значение 111. Вывели 111. Стоит упомянуть, что выполнение кода в языках программирования, оно, в частности, в GL, оно происходит сверху вниз. То есть шестая строчка выполнится первой, за ней выполнится седьмая строчка, за ней выполнится восьмая, но так как восьмой

84:46

Speaker A

ничего нету, то ничего не выполнится. За ней выполнится девятая, за ней выполнится десятая. Поэтому порядок вывода наших переменных, он играет роль.

84:55

Speaker A

Видите, мы сначала вывели Gameover, потом вывели 111. Оно так и вывелось. Сначала Gameo Oover, потом 111. Если бы мы выводили их по-другому, то есть, допустим, сначала мы бы выводили, ну, скоore, то есть 111, а потом бы мы выводили только Gameo Overover, то

85:11

Speaker A

давайте посмотрим, что было бы. Я вот очистил терминал, просто правая кнопка мыши и тут вот кleр, то есть, ну, или очистить, там, удалить, чтобы просто не мешали наши предыдущие запуски программы. Сохраняем файл. Обязательно не забываем.

85:25

Speaker A

И опять запускаем нашу программу. Видите, в этот раз у нас сначала вывелось 111, а потом Gameover.

85:33

Speaker A

То есть, если мы их меняем местами, то от этого меняется результат выполнения нашей программы, потому что программа выполняется сверху вниз. И это важно учитывать. Если мы сначала выведем текст, а потом скор, выведется сначала текст, а потом скор. Если мы сначала

85:50

Speaker A

выведем скор, а потом текст, файл сохраняем обязательно. то сначала выведется, соответственно, скоore, да, как мы и выводим, а потом только текст. То есть давайте опять же разберём, что вообще происходит в этой программе. Мы идём, то есть запускаем файл main GO, видим, что это

86:10

Speaker A

главный пакет, что это главный кусок кода, да, вот это всё кусок кода. Кусок кода, который называется main. Как понять, где кусок кода начинается, а где заканчивается? Это можно по скобочкам.

86:21

Speaker A

То есть вот видите main. Сразу же идут скобочки, которые говорят, где начинается, где заканчивается этот кусок кода. Вот он. Всё, что между скобочками - это кусок кода, который относится к main, который относится к функции main.

86:32

Speaker A

То есть функция main - это самый главный кусок кода, откуда начинается выполнение. Ну, по сути, в данный момент он у нас сейчас единственный. Вот.

86:39

Speaker A

Переходим опять же главный кусок кода, поэтому начинаю выполнение отсюда. Сверху вниз идём. Шестая строчка. Язык программирования. Я хочу, чтобы ты отдал команду компьютеру. создать переменную, которую, которую необходимо назвать текст и положить в неё значение game over. То есть, так как у нас вот в

86:58

Speaker A

кавычках, да, это значение, то язык программирования понимает, что это просто обычная строчка, потому что у нас опять же строчка - это один из доступных типов данных. Помимо прочего, там есть дробные числа, есть целые числа и есть ещё некоторые другие типы данных,

87:11

Speaker A

которые, опять же, попозже мы разберём. Шестая строчка. Создай переменную, которую назови текст. Положи в неё значение Gameover. Вот наша программа, в которой ничего нет, когда она только запустилась. Создаём переменную текст со значением Gameover. Всё, создали переменную текст со значением Gameo

87:28

Speaker A

Oover. Вот она у нас теперь, эта переменная располагается в оперативной памяти. Она имеет название, которое мы ей передали. Она имеет значение, которое мы ей передали. Далее, седьмая строчка.

87:40

Speaker A

То же самое, только создай переменную, которая называется Score, и положи в неё 11 1. Опять же мы переходим, и в оперативной памяти создаётся наша переменная, которая называется Score и у которой значение 11 1. Вот то, что мы с

87:57

Speaker A

вами сделали вообще с компьютером, когда написали шестую и седьмую строчки. То есть в данный момент мы вот стоим на восьмой строчке, да, где ничего нету. И уже в данный момент мы ещё даже не перешли к ящику инструментов FMТ, но уже

88:12

Speaker A

в данный момент наша программа успела выгрузиться в оперативную память. И наша программа успела создать в этой самой оперативной памяти две переменные.

88:20

Speaker A

Первая - это текст со значением Gameover. Вторая - это Score со значением 111. То есть вот так вот на иллюстрации понятно, я надеюсь, как мы своим кодом, как мы тем, что мы просто пишем какие-то буквы, мы этим самым с

88:34

Speaker A

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

88:56

Speaker A

переменные в памяти. Нас это вообще не касается. Всё, что мы можем делать, всё, что нам необходимо делать - это написать текст равно game over ср = 111. И мы этими буковками создаём переменные, создаём, сохраняем значения, которые в будущем можем использовать. В данный

89:17

Speaker A

момент мы их используем просто для того, чтобы потом вывести на экран. Всё. Вот у нас тут переменный текст со значением Gameover, переменная скоore со значением 111 и переходим к девятой строчке. Берём ящик с инструментами FMT, берём из него

89:34

Speaker A

инструмент printalent, который просто выводит на экран какое-то значение и переносит курсор на новую строчку. И выводим переменную Score. Опять же инструмент println, он просто смотрит, что за значение лежит в переменной score, залазит в переменную Score, видит, ага, 111 и выводит эту 111 на

89:55

Speaker A

экран. Потом десятая строчка, опять берём ящик с инструментами FMT. Опять print llen инструмент берём, только уже выводим переменную текст. Опять же Print LN он идёт, смотрит, что там лежит в переменной текст, видит, ага, game over и выводит это на экран. Давайте

90:13

Speaker A

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

90:26

Speaker A

переменная скора. Вот тут значение 111 у нас. И мы вводим это на экран. Давайте ещё раз запустим программу. А я хочу сказать, что в дальнейшем я буду сохранять файлы. То есть нам необходимо перед каждым запуском программы сохранять её файлы для того, чтобы

90:39

Speaker A

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

90:51

Speaker A

сохранения. То есть вот на MacOS - это Command S, на винде, на Linux - это Ctrl S. Ну вот буду нажимать Command S, то есть Command S. Оп, всё, файл сохранился. Вот мы с вами восьмой строчке создали переменную Score,

91:04

Speaker A

положили в неё 111, а потом можем перезаписать это значение и положить туда, например, 50. Почему изначально я пишу двоеточие перед знаком равно, а потом не пишу? Потому что двоеточие пишется только тогда, когда переменная именно создаётся. То есть, когда мы

91:21

Speaker A

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

91:35

Speaker A

111. Потом я в десятой строчке в переменную скор кладу значение 50. То есть, что происходит? Я просто беру и вот так вот перезаписываю это значение.

91:43

Speaker A

Тут будет 50. Соответственно, когда мы будем выводить на экран, тут будет 50. Сохраняю файл, запускаю программу.

91:50

Speaker A

[аплодисменты] 50. В чём тут у нас есть ограничение? Некоторые. Го - это статически типизированный язык. Что это значит? У каждой переменной есть какой-то тип. У переменной текст- тип строка. У переменной скор тип целое число. И мы, когда создаём переменную, то ей

92:09

Speaker A

автоматически присваивается какой-то тип. Ну, судя по тому значению, которое мы в неё кладём. И в дальнейшем в уже созданную переменную типа текст, типа строка, мы не можем положить целое число. Мы можем положить только строку.

92:25

Speaker A

Точно также с переменными типа целое число. Мы, если создали переменную с типом целое число, то далее в неё положить мы можем только целое число.

92:34

Speaker A

Давайте посмотрим, что будет, если я в переменную текст захочу положить на значение там 15. Опа, подчёркивает нам сразу редактор кода. Опять же, преимущество редакторов кода нам подчёркивают ошибки. Наводим, смотрим.

92:46

Speaker A

Мы не можем использовать 15, потому что это тип целое число, как строку в присваивании. То есть мы не можем как бы, да, целое число присвоить в строке, потому что тип переменной текст у нас определился в шестой строчке, и это строка. Точно так же мы

93:02

Speaker A

не можем в переменную скор положить строку. То есть давайте попробуем с равно hello. Точно так же подчёркивает, наводим. Мы не можем использовать hello, типа строка как целое значение. Ну, потому что у нас как бы в скоore можно только целое значение класть, а мы хотим

93:19

Speaker A

положить строку. Поэтому опять же это называется строгая типизация, что в самом начале, если мы задали какой-то тип переменной, то этот тип мы уже не можем поменять. Мы можем любое значение этого типа поставить в переменную, да?

93:34

Speaker A

То есть вот, если изначально тип переменной целое число, мы можем туда поставить любое другое целое число. 50 я могу написать скор равно там 100. Вот такое вот вообще вот длинное число, потом запустить программу, вывести на экран. Вот оно будет. Я могу, потому что

93:49

Speaker A

это всё целые числа. Но как только я захочу сюда положить строку, он мне скажет: "Иди, дядя, гуляй". Что, типа, я не могу положить строку в целое число.

94:00

Speaker A

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

94:14

Speaker A

работаем, чтобы он точно знал, что если мы с вами обращаемся к скор, значит, это целое число. Вот оно у нас скор целое число. И все операции дальнейшие производить с переменной скор как с целым числом. Это очень много времени

94:30

Speaker A

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

94:44

Speaker A

И ничего не будет, как бы, никакой ошибки, всё отработает корректно. Но для того, чтобы поддерживать вот такую типизацию, как в Питоне, нужно очень много производительности на это тратить и очень много процессорного времени.

94:55

Speaker A

процессорного времени, которое могло бы пойти на то, чтобы выполнять вашу программу, а оно идёт на то, чтобы узнать, какой же там тип. Поэтому это всё на плечи программистов кидается.

95:05

Speaker A

Слежка за тем, какой конкретно типу переменной и использование этой переменной только с конкретным типом.

95:11

Speaker A

Зато мы выигрываем очень много процессорного времени. Значительно быстрее наша программа начинает работать. Мы можем переменные создавать и мы можем класть в них какое-то значение. Давайте вот, например, тоже в переменную текст. Я положу новое значение. текст равно, ну, тоже Hello

95:25

Speaker A

World, в принципе, почему бы и нет. Можно вот три восклицательных знака. Сохраняю файл, запускаю программу. И вот мы видим, мы создали переменные наши текст и score. И хоть изначально в них было значение Gameover и 11, вывелось у нас вот это большое число и другой

95:41

Speaker A

совсем текст. Почему? Да потому что мы их вот тут вот перезаписали. Вот. Вот здесь вот мы перезаписали с вами скоe.

95:48

Speaker A

Здесь мы перезаписали с вами текст. То есть у нас вот здесь вот перед тем, как вывести сore, было уже вот это вот большое число, а в переменной текст у нас уже был с вами вот этот вот Hello World. Мы просто это перезаписали и

95:59

Speaker A

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

96:12

Speaker A

переписывать это значение на результат какого-то выражения. Что я имею в виду? Мы можем в переменную скор класть не просто 50, а 50 + 10. 50 + 10 - это 60.

96:24

Speaker A

Соответственно, мы в переменную, которая стоит слева знака равно, будем класть результат значения выражения. То есть мы уже начинаем по чуть-чуть использовать язык программирования как некий такой калькулятор. То есть вот в скоore мы можем записать 50 + 10. Соответственно,

96:37

Speaker A

в скоore будет 60. Давайте запустим программу 60. То есть ещё раз, что тут произошло? Мы создали переменные геймоверы 111. Вот они у нас опять же, вот наша программка занимает какое-то место в памяти. И вот мы создали две переменные текст со значением Gamover и

96:52

Speaker A

score со значением 111. Потом в девятой строчке мы в переменную Score записали результат выражения 50 + 10. То есть процессор посчитал вот это 50 + 10, понял, что это 60 и записал это в скор.

97:04

Speaker A

То есть тут мы просто переписали с вами значение на 60 и вывели это на экран. Ну и, соответственно, вот результат. Но ещё в выражении мы можем использовать не только какие-то константы, какие-то литералы, типа вот заранее прописанные в коде числа, типа 50 или 10. А мы можем

97:21

Speaker A

использовать также значение переменной. То есть мы можем написать скор вместо любого из этих литералов скор. Что тут будет происходить? Изначально у нас скоore равен 111. Дальше мы пишем, что скоe. Запиши в переменную скор результат следующего выражения. Скоore + 10. Что

97:39

Speaker A

это значит? То есть, что тут будет происходить? Мы берём и говорим, что запиши, пожалуйста, в переменную скор, потому что она слева знака равно.

97:46

Speaker A

Значит, в эту переменную мы будем записывать. Запиши в эту переменную результат выражения, которое стоит справа от знака равно. То есть запиши в переменную скор результат вот этого выражения. Выражение скор + 10. Что это значит? Берётся переменная скор, смотрится, какое лежит в ней значение.

98:04

Speaker A

111. Соответственно, 111 + 10 - это 121. И потом выводим это на экран. Давайте посмотрим, что выведется. Сохраняю файл, запускаю программу 121, да? То есть мы можем вот так вот брать и уже не просто отталкиваясь от каких-то там чисел, да,

98:20

Speaker A

рандомных, там 50, там 5.032, там 102, вообще любые, мы можем отталкиваться в результатах своих выражений от конкретных переменных. Например, вот скоore, да? То есть мы можем в скор записать результат выражения скор + 102, то есть 111 + 102. Ну и что тут будет у

98:40

Speaker A

нас? Правильно, 213. Проверяем 213. Как мы можем это использовать? Давайте попробуем написать некую такую симуляцию нашего флапибёрда небольшую. В чём вообще заключается вот эта вот переменная, да, счёт, которую мы с вами имитировали? То есть вот она у нас изначально ноль, да, запустили. У

99:01

Speaker A

нас переменная скор нулю равна. После этого мы начинаем лететь, пролетаем первую трубу. Один. Оп, скорб переписывается один. То есть откуда взялось один? Мы знаем, что мы до этого ещё ни одной трубы не пролетели, что у нас до этого ноль труб. И мы пролетаем

99:19

Speaker A

очередную трубу и прибавляем единицу к уже имеющимся трубам. Но так как их было ноль, то 0 + 1 - это о. Далее пролетаем ещё одну трубу два. То есть мы знаем, что у нас до этого в памяти уже сохранена

99:32

Speaker A

переменная скор. Она была единичке равна, но мы пролетели очередную трубу, и у нас стало два. Две трубы мы пролетели на счёт два. Летим дальше, пролетаем третью трубу. Счёт стал три.

99:45

Speaker A

Три. Почему? Потому что мы знаем, что мы уже до этой трубы пролетели две. И пролетая очередную трубу, нам нужно просто к тому количеству труб, которые мы уже пролетели, прибавить единицу.

99:58

Speaker A

прибавляем к двойке единицу, получаем тройку. Ну и так дальше. Четыре. Почему четыре? Да потому что мы уже три трубы пролетели и пролетаем очередную трубу.

100:07

Speaker A

Значит, 3 + 1 4. Мы запоминаем, что мы пролетели четыре трубы. Вот мы в нашем счёте запомнили. То есть, если мы пролетим очередную трубу, то мы просто прибавим единичку к тому значению, которое лежит в переменной скор. Оп, пролетели очередную трубу. У

100:23

Speaker A

нас счёт пять. Почему пять? Да, потому что былочетыре и плюс о 5. То есть уже примерно, наверное, может стать понятно, для чего в принципе используются переменные. Для того, чтобы хранить какие-то значения и чтобы их использовать. В данном случае мы храним

100:39

Speaker A

наш счёт в переменной скоро. Для чего мы его храним? Да, для того, чтобы знать, сколько мы уже пролетели труб и чтобы понимать, сколько у нас в очередной раз нужно показывать счёт пользователю, потому что без переменной, без использования памяти, без запоминания

100:56

Speaker A

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

101:09

Speaker A

место. И вот смотрите, вот пролетели мы эту трубу. А какой счёт? Да не знаю. Я до этого не считал трубы. Как я узнаю, какой счёт? Я нигде не запомнил, сколько я уже пролетел труб. Ладно, а сейчас какой счёт? Тоже

101:22

Speaker A

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

101:40

Speaker A

потом использовать это число, чтобы понимать. Ага, 10. Значит, дальше я, если пролечу, 11, для этого используется переменная. И сейчас я вот скажу такую вещь. Не нужно сразу пытаться представить, как бы вы это делали, потому что мы это разберём чуть позже.

101:55

Speaker A

Но в переменную можно сохранять не только какие-то числа, не только текст, но ещё и более сложные структуры.

102:05

Speaker A

Например, можно в переменную сохранить пользователя социальной сети. Вау. То есть у нас есть какой-то пользователь, у него есть аватарка, у него есть имя, фамилия, и всё это в сумме - это какой-то пользователь. И пользователя социальной сети точно также можно

102:21

Speaker A

сохранять в переменную. Точно также можно получать значение этой переменной и их перезаписывать. Например, пользователь поменял себе фамилию там во ВКонтакте. Мы взяли и переписали это значение переменной. Пользователь поменял номер телефона, мы взяли к этой переменной обратились и переписали. И,

102:37

Speaker A

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

102:51

Speaker A

видите на экране, всё, что вы видите, когда используете какое-то приложение, это всё переменный. Используйте Яндекс-Такси. Видите, как у вас на экране бежит машинка, да, и показывает, как близко к вам водитель. Водитель в программе тоже представлен как переменная, как набор каких-то

103:08

Speaker A

координат как машина, на которой он едет, его имя и аватарка. Всё вместе - это водитель.

103:15

Speaker A

Точно также вы в системе представлены просто как переменная. У вас есть тоже какая-то аватарка или у вас есть рейтинг и у вас есть путь, куда вы хотите доехать. Это всё представлено в виде переменной. для того, чтобы с этими

103:29

Speaker A

данными можно было как-то работать, для того, чтобы их можно было сохранять и чтобы с ними можно было как-то взаимодействовать. Для этого нужны переменные. То есть точно так же, как мы сейчас взаимодействовали с переменной Score в нашем Flppy Bird, точно также

103:41

Speaker A

идёт взаимодействие с пользователями, с водителями в более сложных системах, да, там неважно, это социальная сеть или Яндекста такси или там какой-нибудь видеохостинг. Всё представлено в виде переменных и в виде какой-то работы с этими переменными. более сложные переменные, более сложное с ними

103:59

Speaker A

взаимодействие мы рассмотрим с вами чуть подальше. Давайте вернёмся в нашу программу и напишем, ну, такую небольшую эмуляцию флапибрда, да? То есть давайте посмотрим, что вообще у нас представляет Flppy Bird. Изначально у нас, когда Flppy Bird запускается, что у нас

104:13

Speaker A

выводится на экран? Get ready, да, выводится. Ну, давайте запомним это в какой-нибудь переменной. То есть, ээ, приветственный текст. В принципе, я могу его назвать текст один, то есть текст о равно get ready. Вот у нас get ready. Потом, когда

104:30

Speaker A

наша птичка уже врезается в какую-то трубу, нам пишут Gameo Oover. Да, давайте тоже запишем это текст 2. Я это назову текст 2 Gameover. Ну, у нас вот тут уже есть какой-то текст Gameover. Я его сотру. Вот Game Ready сначала

104:46

Speaker A

вводим, потом Game Over. Также у нас есть с вами наш счёт, да? чтобы считать, сколько мы труп уже пролетели. Ну и скор. Изначально скор у нас сколько в самом начале? Давайте вот просто посмотрим. Я думаю, многие уже догадались, сколько у нас в самом начале

105:01

Speaker A

счёт. В самом начале счёт ноль, потому что мы ещё ни одной трубы не пролетели.

105:05

Speaker A

Счёт ноль. Ну и вот наша программа. Тут она вот уже у нас три переменные в ней, поэтому она чуть побольше памяти занимает. Вот представление. Опять же, ребят, это довольно всё условно, но где-то отдалённо, примерно так оно и работает, как я вам показываю. То есть я

105:22

Speaker A

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

105:36

Speaker A

как это всё выглядит на самом деле. Вот у нас три перемены. текст о со значением get ready, текст 2 со значением Gameo Oover и Score со значением ноль. Давайте я сюда тоже напишу ноль. Вот это всё стираем. И,

105:52

Speaker A

соответственно, можем пока просто вывести их на экран. То есть сейчас это подчёркивается, потому что мы объявили эти переменные, но нигде не используем.

106:00

Speaker A

А тут подчёркивается, что мы хотим вывести несуществующую переменную. То есть у нас как бы больше нету никакой переменной текст. У нас есть текст один, текст 2. Ну и, соответственно, давайте выведем всё, что у нас есть. Стрём и заново напишем. Сначала выведем текст

106:14

Speaker A

один, потом выведем текст 2, потом выведем score. Сохраняю файл. Очищу терминал. Вот можно правой кнопкой мыши нажать.

106:27

Speaker A

Тут clear. И пишу run go. Вот выводится значение наших переменных. Треде, game over. Ну и score ноль, да, вот всё ноль. Ну и, соответственно, опять же, в том же порядке, что мы и написали, потому что выполнение программы идёт сверху вниз. Мы сначала

106:45

Speaker A

запускаем главный кусок кода, в нём создаём переменную первую. Вот наша первая переменна текст один, потом вторую переменную текст 2. Вот она у нас тут создаётся. И скору мы создаём, да, и с соответствующими значениями. То есть, ну, в скоро у нас лежит ноль. Потом

107:00

Speaker A

выводим их на экран. Опять же сверху вниз идёт выполнение, поэтому сначала выведем текст один вот get ready, потом текст 2, выведем Game Over и score. То есть у нас там нолик. Теперь давайте начнём эмуровать нашу Flappy Birds игру.

107:14

Speaker A

Удалю все выводы. Первым делом у нас в сводится getтреy, то есть, ну, приготовиться. Давайте выведем FMT, printl 1. Всё, у нас выведится. Дальше мы можем сразу же вывести счёт. Смотрите, сейчас покажу несколько более продвинутый уровень использования инструмента Printn из

107:34

Speaker A

ящика инструментов FMT- это вывод сразу нескольких значений в один вызов этого инструмента. То есть как это выглядит.

107:43

Speaker A

То есть я, например, могу разом вывести сразу две переменные. Как это выглядит? FMT printl и давайте сразу текст 2 запятая score. Я могу вот так вот это всё вызвать. Что будет? Да, просто выведется переменная текст 2 и потом

107:57

Speaker A

через пробел выведется переменная score. Давайте сохраним файл, запустим. И как мы видим, то, что у нас раньше выводилось на новой строке, теперь выводится в ту же самую строку через пробел, да? То есть мы можем, по сути, сразу все три эти переменные вывести в

108:11

Speaker A

одну строчку одним вызовом инструмента print ln, и он выведет все эти переменные через пробельчик и в конце просто перенесёт курсор на новую строчку.

108:22

Speaker A

Сохраняю файл, запускаю. Вот, как мы видим, Game over 0. Но мы можем выводить так не только переменные, но ещё и комбинировать это с выводом какого-то рандомного текста, который мы просто можем написать ровно так же, как мы с вами писали Hello World. То есть как это

108:39

Speaker A

может выглядеть. Вот пишу FMT print ln и ваш счёт двоеточие и через запятую скорб. То есть вот тут вот то, что в кавычках, это какая-то строка. И потом через пробельчик я выведу счёт. Как это будет выглядеть? Сохраняю файл,

108:58

Speaker A

запускаю. Ваш счёт ноль. И таким образом мы можем себе довольно сильно упростить взаимодействие с выводом на экран. Как я хочу использовать вот этот приём, который я вам показал? Да очень просто. Сначала я вывожу просто Gреди, то есть текст один,

109:15

Speaker A

а потом сразу выведу ваш счёт. Ну, сейчас программа не запустится, потому что, как я вам объяснял, мы с вами создали переменную, которую нигде не используем. И поэтому нам язык программирования говорит, что давай ты либо используешь эту где-то переменную,

109:28

Speaker A

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

109:42

Speaker A

Удаляю, сохраняю и запускаю. Вот у нас вводится getре, ваш счёт ноль. То есть в самом начале, примерно как и в приложении, да?

109:55

Speaker A

Вот getтреy и счёт ноль. Дальше смотрим. Мы можем пролететь первую трубу, да? Давайте это просто смулируем как бы выводом на экран. FMT Printl. Вы пролетели через трубу и заново можем вывести наш счёт.

110:14

Speaker A

То есть я вот это скопирую. и вставлю. Сохраняю, очищу терминал, запускаю getреди. То есть приготовьтесь, ваш счёт ноль. Вы пролетели через трубу, ваш счёт ноль. Но так работать не должно, да? Ведь когда мы с вами пролетаем через трубу,

110:32

Speaker A

ноль один. То есть мы, когда пролетаем через трубу, у нас счёт увеличивается на один, а у нас почему-то так и осталось ноль. Почему? Ну, потому что мы после того, как пролетели через трубу, мы никак не изменили наш счёт. Хотя,

110:46

Speaker A

по-хорошему-то он должен был увеличиться на один. Ну, в принципе, уже изменять значения переменных мы умеем. Мы можем написать следующую конструкцию: score равно score + 1. Что тут произойдёт? Мы говорим после того, как пролетели через трубу, что возьми, пожалуйста,

111:03

Speaker A

переменную скор и запиши в неё результат следующего выражения. Скор плю 1. Скор у нас на этот момент 0.

111:11

Speaker A

0 + 1 1. Соответственно, в переменную скор запишется единица, и наш счёт выведется единица. Да. Вот сюда вот мы перезапишем один и выведем это на экран. Сохраняю файл, запускаю. И как мы видим, приготовьтесь, ваш счёт ноль. Вы пролетели через трубу, ваш счёт один.

111:30

Speaker A

Всё. Теперь мы можем, в принципе, просто взять, написать ещё раз FMТ. printl. Вы пролетели через трубу, то есть второй раз пролетаем через трубу и опять увеличиваем наш счёт на один. И опять выводим наш счёт, то есть ваш счёт score. Давайте запустим. Очищу

111:57

Speaker A

терминал. Запускаю. Гтрейде. Ваш счёт ноль. Вы пролетели через трубу. Ваш счёт один. Вы пролетели через трубу. У вас счёт два.

112:08

Speaker A

Всё, мы, в принципе, можем полностью это скопировать. Копи вставить и увидеть, что мы опять пролетим через трубу. Опять у нас счёт изменится на один и опять он выведется на экран. Соответственно, ноль.

112:22

Speaker A

Пролетаем через трубу, прибавляем единичку. Счёт один. Опять пролетели через трубу, прибавили единичку. То есть к единичке прибавили единичку, записали в результат. 1 + 1 = 2. Записываем в скор 2, вводится 2. Ну и тут то же самое. В скоре уже лежит два. Мы к

112:40

Speaker A

двойке прибавляем единицу, получаем тройку. Результат этого выражения записываем в скор. Соответственно, в скор будет три и вы видится на экран три. Сохраняю файл, очищаю терминал и запускаю. Вот счёт ноль. Пролетели через трубу один. Опять пролетели через трубу два. Пролетели через трубу три. Ну и

112:59

Speaker A

давайте в конце представим, что мы, допустим, с вами там столкнулись с каким-то препятствием FMT Printl врезались в трубу. Врезались в трубу и выведем наш текст, который обозначает то, что игра окончена.

113:15

Speaker A

Давайте опять создадим эту переменную, потому что теперь-то мы её уже будем использовать, и мы можем её создать, чтобы использовать. И не будет язык программирования жаловаться на то, что мы создали переменную, которую не используем, потому что мы её будем

113:26

Speaker A

сейчас использовать. Текст 2 равно game over. Вы врезались в трубу и FMT print ln. Можно вот текст 2. То есть в конце после того, как мы врезались в трубу, можем вывести Gameo Oover. Очищу терминал, запускаю. Get ready. То есть

113:45

Speaker A

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

114:01

Speaker A

увеличивается на один. Вот 0 1 2 3 4 5. Итак, сколько раз вы напишете, столько раз у нас и увеличится счёт. Вот ещё раз более наглядно, да, для чего нам тут нужны были переменные. Для того, чтобы хранить счёт и хранить вывод, который мы

114:17

Speaker A

хотим сделать. По сути, от этих переменных мы ещё могли бы отказаться и просто вначале вывести вот таким вот образом getреady, а тут вот таким вот образом Gameover, да, и в принципе тут нам переменные особо не нужны, что мы

114:31

Speaker A

сразу выведем на экран это значение, что мы его сохраним в переменную и потом выведим переменную на экран. В принципе, это одно и то же. Но конкретно переменная скор тут уже незаменима, потому что мы в ней хранили наш счёт и

114:44

Speaker A

знали, какой у нас текущий счёт, и знали, какой должен быть счёт после каждого пролёта трубы. Если бы у нас переменной скор не было, мы бы после каждого пролёта трубы не знали, какой у нас счёт. Точно так же, как я вот тут

114:57

Speaker A

вот показывал, что мы можем вот так вот попробовать узнать, какой счёт. Вот пролетел через трубу, да, я вот перемотал. Какой счёт? А сейчас какой счёт? А сейчас какой счёт? Да, непонятно, потому что мы не знаем, мы не видим, какое у нас значение переменной

115:11

Speaker A

скор. А вот так. А, девять. Понятно. Значит, сейчас я пролечу трубу, будет 10. Понятно. Сейчас 11. Ага. И опять, если у нас не было бы переменно, мы бы не знали, какой счёт, не хранили его нигде. Вот какой сейчас, вот сейчас

115:24

Speaker A

какой, да, непонятно. Ну, не сказать точно. А если мы храним это значение где-то, то можно точно сказать. Давайте посмотрим, какие у нас ещё есть распространённые типы переменных. Ну, первое - это целое число, понятно. Текст мы также знаем, да? Можно

115:42

Speaker A

текст. Hello, просто сюда напишу. Также есть у нас дробные числа. То есть, если мы с вами положим в переменную скор целое число, то потом мы не сможем работать с этой переменной как с дробным числом. Давайте покажу, что такое

115:56

Speaker A

дробное число, как оно вообще выглядит. То есть у нас есть, ну, давайте я так вот по-английски назву дробь.

116:03

Speaker A

равно 0 с по и можем вывести это всё на [аплодисменты] экран. Сохраняю. Отчищаю терминал.

116:18

Speaker A

Запускаю программу. Вот. Hello 05. 0,5 - это уже дробное число. То есть в языке программирования под капотом целые числа и дробные числа хранятся по-разному. Чтобы понять, почему именно так, нужно очень сильно углубиться в устройство памяти, устройство хранения информации в этой памяти. Поэтому просто

116:40

Speaker A

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

116:56

Speaker A

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

117:10

Speaker A

Соответственно, это разные типы данных. Соответственно, мы так же, как мы не могли в текст положить целое число, точно также мы в целое число не можем положить дробь. То есть вот, например, у меня есть скор, да, переменная типа целое число. И в это целое число я хочу

117:27

Speaker A

положить дробь. Ту же там, ну, 0,7. А я не могу, потому что мы не можем использовать дробное число в целое число. С точки зрения языка программирования целое число называется int, дробное называется flotт. Просто нужно запомнить, что это такое название

117:43

Speaker A

типов данных. И дальше я буду их использовать, что целое число - это int. Дробное число - это flot, ну и, собственно, строка - это по-английски string. Поэтому опять же необходимо довольно чётко следить за типами данных и за тем, что куда мы присваиваем. Ну,

117:58

Speaker A

если мы что-то не туда присвоим, то редактор кода нам подскажет, что где-то закралась ошибка. Опять же, если я там в текст захочу положить дробное число, он скажет, что типа ты не можешь положить флот, то есть дробное число, в стринг,

118:10

Speaker A

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

118:21

Speaker A

Чтобы объяснить, что это за тип данных, я приведу некоторую аналогию с подпиской на YouTube канал. То есть, допустим, у нас есть канал какой-то, абсолютно любой, допустим, в данном случае Mr Beast, и я могу быть подписан на этот канал, а могу быть не подписан. То есть

118:39

Speaker A

я сейчас подписан на этот канал? Нет. А вот так вот. А вот так я на канал подписан. То есть у меня есть два состояния, как у пользователя системы YouTube. У меня есть два состояния подписки на канал. Я либо подписан, либо

118:53

Speaker A

не подписан. Вот с точки зрения программирования, как бы можно было хранить эту информацию? То есть мне нужно хранить информацию о том, подписан ли пользователь на YouTube канал. То есть есть только два состояния: не подписан и подписан. Третьего не дано.

119:11

Speaker A

По сути, мы могли бы это всё хранить в какой-нибудь строке, да, и просто выводить это всё на экран. К примеру, ну вот, допустим, у нас есть переменная, я назову её subscribed, то есть с английского подписан, и хранил бы в ней строку, да,

119:29

Speaker A

и потом вывел бы это всё на экран. Давайте посмотрим, что у нас вводится на экран. Да, нам выводится, да. Ну и также я тут мог бы хранить слово нет.

119:48

Speaker A

И мы бы узнавали, что да, подписан пользователь или да не подписан. Но в чём тут проблема? Казалось бы, всё удобно, всё просто. Если мы подписаны, мы храним, да, и можем вывести это на экран. Или если мы не подписаны, мы

120:02

Speaker A

можем хранить нет и тоже выводить это на экран. Но в чём тут проблема? В том, что мы таким образом используем память очень неэффективно. Мы храним несколько символов. То есть строка - это несколько символов. Они, каждый символ занимает какое-то место в памяти. И мы, чтобы

120:21

Speaker A

хранить состояние, либо да, либо нет, по сути, у нас только два состояния может быть. Либо подписан, либо не подписан.

120:28

Speaker A

То есть только два состояния, не три, нету третьего какого-то состояния, и их не может быть меньше двух. То есть только два состояния: либо подписан, либо не подписан. И мы для хранения такой простой информации с вами выделяем для это слишком много памяти, когда

120:45

Speaker A

храним это всё в строке. То есть нам необходимо каждый символ выделить на каждый символ какое-то количество байт, закодировать этот символ. Это всё очень много занимает места. Поэтому для таких случаев, когда нам нужно хранить какую-то информацию, которая может принимать только два значения, либо

121:06

Speaker A

правда, либо неправда, то есть вот, допустим, подписан я на этот канал, правда, а вот так. Подписан на этот канал, неправда. Вот для такой информации придумали тип данных булин. В чём его преимущество? По сути, он под капотом хранит то же самое. Либо да, в

121:24

Speaker A

него можно записать, либо нет, но формат данных представляет собой наиболее оптимизированный вид, благодаря чему во много-много раз меньше памяти мы расходуем для хранения этой же самой информации. То есть как это выглядит вообще в языке программирования. То есть subscbed. Вот давайте сейчас посмотрим.

121:48

Speaker A

Вот типа я subscribed. Давайте подпишемся. Ну да, я подписан. Тут нам нужно написать, да, соответственно, опять можем вывести на экран. Вот. Да.

121:58

Speaker A

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

122:12

Speaker A

может быть ложью, то, что я могу быть не подписан. Всё, третьего не дано. Тип данных булин. Выглядит он следующим образом. То есть, чтобы хранить в типе данных булян слово да, нам нужно написать true. True с английского переводится как правда. Что это значит?

122:26

Speaker A

Что мы храним тут значение правда. Subscribed. Правда. Ну, типа, да, правда. Я подписан. Действительно, давайте сохраним, выведем на экран.

122:35

Speaker A

Очищу консоль, вывожу на экран. True, то есть true с английского правда подписан. Правда, можно даже чуть-чуть дополнить наш вывод по предыдущим примерам. Сразу выведем здесь.

122:49

Speaker A

подписом на мистера Биста, и ответ будет у нас true, то есть правда с английского. Выводим. Подписан на мистер Биста. True. А если я не подписан? Вот я не подписан, тогда false. Fse английского ложь, то есть не подписан. Сохраняем файл, запускаем

123:12

Speaker A

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

123:31

Speaker A

такой тип данных булин, который представляет из себя либо правду, либо ложь, он встречается просто повсеместно.

123:38

Speaker A

Подписаны ли вы на канал или не подписаны? Поставили ли вы под каким-то видеороликом лайк или не поставили?

123:45

Speaker A

Оплатили вы заказ или не оплатили, добавили вы товар в корзину или не добавили. Вся эта информация, она для наиболее оптимального вида представлена типом данных буon, который опять же может в себе содержать либо true, либо false. Или, например, закрыт у вас

124:03

Speaker A

профиль в социальной сети или нет. как, например, вот во ВКонтакте или в Инстаграме можно закрывать себе профиль в социальной сети и там просто точно такая же переменная типа bule, которая содержит в себе fse, если вы не скрыли свой профиль, да? То есть вот, например,

124:20

Speaker A

можно переменную назвать hй, то есть hidenй - это скрытый, то есть профиль скрытый. Давайте я тут даже напишу. Вот профиль скрытый. FSE. То есть если FSE это значит, что профиль не скрытый, значит он открытый. Вот профиль скрытый, false. То есть как бы ну

124:42

Speaker A

открытый профиль. А если йден у нас true, тогда профиль скрытый. True, да? То есть профиль скрытый. Правда. Этих примеров можно приводить большое множество. Я надеюсь, примерно логика пока сейчас понятна.

124:57

Speaker A

Может быть, совсем сложно представить, как это вообще потом использовать в реальных программах. Как использовать цифры и числа, которые мы с вами создаём? Как использовать текст, строки, которые мы создаём. Как использовать вот эту непонятную фигню вообще, которая называется булин. Я, если честно, сам,

125:14

Speaker A

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

125:28

Speaker A

обусловиться, что если мы, например, присваиваем нулю, то это значит, что профиль скрытый, да? А если мы присваиваем единице, это значит, что профиль открытый. Тоже так мы могли обусловиться. Но в чём тут опять же минусы? что когда мы объявляем

125:43

Speaker A

целочисленный тип данных, мы сразу резервируем в нашей оперативной памяти очень много места. Очень много места. В то время как були, давайте я чуть-чуть расширю нашу программку, да, в то время как були, он занимает гораздо меньше места. То есть там буквально вот

126:00

Speaker A

вот столечка надо вообще оперативной памяти в сравнении с числом, гораздо меньше. И то есть мы на то количество памяти, в которое мы записали всего лишь одно число, могли бы записать сразу много этих бульонов и тем самым очень сильно мы экономили бы место, просто

126:17

Speaker A

основываясь на том факте, что мы знаем, что всего лишь два значения может быть у этого типа данных. Либо true, либо false. В то время как у числа может быть очень много различных значений, там несколько миллионов, миллиардов. Поэтому мы сразу резервируем под это всё память.

126:36

Speaker A

Нам это не выгодно. Зачем нам с собой тащить сразу миллионы, миллиарды значений, если мы знаем, что у нас их будет только два, ни больше, ни меньше.

126:45

Speaker A

Поэтому был придуман тип данных булин, который может себе содержать либо true, что значит правда, что значит да, либо фолс, что значит ложь или нет. Опять же, там подписаны вы на канал, да, правда.

126:57

Speaker A

Или, может быть, вы, если не подписаны, значит нет, ложь. И это очень много где может применяться. Более подробно мы рассмотрим Булиан чуть далее, совсем скоро. Посмотрим на конкретные примеры, как он используется в коде. Сейчас главное от вас понимание, что такое

127:13

Speaker A

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

127:28

Speaker A

заняли бы слишком много оперативной памяти. А нам не нужно столько оперативной памяти, потому что у нас всего лишь два значения: true или false.

127:36

Speaker A

Поэтому мы выбираем тип данных булян, чтобы оптимизировать это всё в оперативной памяти и не занимать слишком много места. Давайте посмотрим, что мы можем делать со значениями, которые мы с вами создаём и кладём в переменные, помимо того, что выводить их на экран.

127:51

Speaker A

Ну, сложение мы уже прошли, то есть мы можем целочисленно складывать некоторые значения, прибавлять к переменным единичку, 10 мы можем прибавлять.

127:58

Speaker A

Давайте сейчас я это продемонстрирую. Удалю всё, что мы с вами написали, и создам просто переменную скор заново, которая изначально будет равна нулю.

128:06

Speaker A

Потом прибавлю к ней 10 и выведу на экран. [аплодисменты] Вот мы вывели с вами 10. Можно даже подписать, что это наш счёт. Ещё раз запущу. Вот счёт 10. Можем прибавить к нему ещё 20. Запускаем программу. Счёт 30. Почему? Потому что изначально было

128:35

Speaker A

ноль. Потом мы прибавили в скор, записали результат выражения ср + 10. На этот момент скор был ноль. 0 + 10 - это 10. В скор положили 10. Потом в двенадцатую строчку перешли и сказали: "Положи в скор" результат вот этого

128:51

Speaker A

выражения. А это выражение уже чему равно? Скор на этот момент у нас уже 10, да? Запоминаем, потому что мы в десятой строчке записали туда 10. 10 + 20 - это 30. Положили в скор 30, вывели на экран.

129:04

Speaker A

Наш результат 30. Далее мы можем вычитать, помимо того, как складывать, можем ещё и вычитать. Например, скоore с score -15. Запускаем программу 15. Почему? Потому что вот здесь у нас было ноль. Тут стало 10, тут стало 30, а потом мы из тридцати вычли

129:26

Speaker A

15, записали это в скор, получилось 15. Также мы можем производить деление. Скор = поде. То есть у нас в данный момент 15. 15 мы с вами делим на 3, получаем 5. Запускаем программу, видим пть. Можно умножать скор = скор у 10. Что мы сейчас

129:50

Speaker A

увидим? 50, потому что вот здесь вот у нас было пять, а тут уже мы 5 x 10, получили 50.

129:58

Speaker A

Запускаем 50. Стоит сразу оговориться, что когда мы с вами работаем с целыми числами, то во время операции деления могут возникать некоторые странности.

130:08

Speaker A

Давайте покажу пример. Вот у нас переменной скор лежит число 10, и мы хотим его поделить на три. То есть, казалось бы, какой должен быть результат? 10 мы когда делим на три, мы получаем 3це и 1/3, да? То есть

130:24

Speaker A

3 1/3, целая часть и дробная часть. Но давайте посмотрим, что будет, если мы поделим 10 на 3 на языке программирования. То есть опять же в переменную скор мы положим результат деления десятки. Ну, то есть переменная скор, в которой лежит 10 на 3. И теперь

130:42

Speaker A

выведем на экран. Запускаем программу и видим просто три. А где же ещё 1/3? То есть это довольно странно, ведь 10 / 3 - это не 3, потому что 9 / 3 - это 3, а 10 / 3 - это 3це и 1/3. Где

131:00

Speaker A

ещё 1/3? Так вот, 1/3 пропадает, потому что мы производим целочисленное деление. Почему деление целочисленное? Что это вообще значит? Когда у нас делимое - это целое число, когда у нас делитель - это целое число, то в результате у нас

131:19

Speaker A

всегда будет только целое число. Почему? Потому что так договорились разработчики языка программирования и потому что это удобный инструмент нахождения целой части при делении. То есть мы тут можем написать даже 11, в принципе, но всё равно ответ будет три, потому что целая

131:39

Speaker A

часть отделения 11 на 3. Вот 11 / 3, что мы получаем? 3це и 2/3. Целая часть - это 3, дробна 2/3, но целая часть она является ответом в целочисленном делении. Поэтому ответ у нас будет также три. Чтобы это исправить, если мы вдруг

131:59

Speaker A

хотим произвести полноценное деление и узнать результат, включая дробную часть, нам нужно, чтобы делимое было тоже дробью. Ну а дробный тип данных - это у нас флот. И чтобы у нас делимое, то есть скор изначально был дробью, нам необходимо просто добавить тут точка

132:18

Speaker A

ноль. Что произошло? Мы при инициализации переменной создали и записали в неё не целое число, а дробь.

132:26

Speaker A

То есть даже если навести, нам показывает, что скоore теперь типа флот 64. Что значит 64? - это количество занимаемой памяти. Пока можно в это не углубляться. Просто флот, да? Если мы сотрём точка ноль, то мы увидим, что тип

132:41

Speaker A

данных in, то есть целочисленный. Если точка ноль напишем, то сразу это даёт языку программирования понять, что мы хотим работать со скор именно как с дробью. Можем точка пть написать, точка что угодно, но можно точка ноль, если мы хотим конкретно 11, но при этом, чтобы

133:00

Speaker A

язык программирования воспринимал это как дробь. И теперь, так как у нас делимая - это дробь, то результат этого выражения будет тоже дробь. То есть, если мы дробь делим на целое число или дробь делим на тоже дробь, результатом будет дробь. И мы увидим, наконец-таки,

133:18

Speaker A

нашу дробную часть. Сохраняем файл, запускаем программу. И видим результат. 3 2/3. Ну, 2/3 - это как бы 6 в периоде, то есть 666 и так до бесконечности. Ну, тут вот некоторые округление происходят по магическим правилам, просто чтобы нам не забить

133:36

Speaker A

весь компьютер бесконечным выводом шестёрок. Также язык программирования Goeng у нас поддерживает нахождение остатка отделения. Что такое остаток отделения? Давайте посмотрим на этом же примере. То есть вы, то есть вот мы с вами 11 делим на 3 и получаем

133:54

Speaker A

3,2/3. Что такое остаток отделения? По сути, остаток отделения - это когда мы берём только целую часть отделения, умножаем делитель на эту целую часть, то есть 3 x 3 - это у нас 9. И потом мы из делимого вычитаем полученное число. 11 -

134:11

Speaker A

9 - это у нас 2. Что такое 2? Это остаток отделения. Почему? Ну, потому что мы вот 11 / 3, получили 3,2/3. То есть у нас целая часть три.

134:23

Speaker A

Соответственно, то число, которое у нас поделилось, собственно-, это 9, потому что 3 x 3 - это 9. То есть у нас как бы 9 по 3, да? А вот этот вот остаток - это два, потому что оно не влезло в деление,

134:38

Speaker A

как бы, да? То есть вот мы сверху к девятке накинули двойку, но всё равно получили трицелых. Ну и, соответственно, мы можем находить остаток отделения. Ну, для начала давайте рассмотрим, собственно, как это выглядит. Давайте вот в переменную целое. Вот я вот назову

134:53

Speaker A

целое. Ну, а так как у нас целое ещё не было создано, да, так как мы его тут впервые создаём, не перезаписываем уже существующую переменную, а создаём новую переменную целое, то тут нужно ставить двоеточие. Двоеточие нам как бы в первую

135:07

Speaker A

очередь и нам, и языку программирования говорит, что в данной строчке слева от двоеточия равно создаётся новая переменная. Нужно выделить новую память, да, в оперативной памяти. Вот опять же целая. Давайте выведем скоe. Запятая целая. Мы можем и три, ичетыре, и пять,

135:25

Speaker A

так и сколько угодно вообще выводить в одну строчку. Запускаем нашу программу. Видим счёт 11, а целая у нас три, да? То есть целая часть отделения. Давайте посмотрим теперь остаток. Остаток. Чтобы найти остаток отделения, нужно написать процент. То есть процент - это значок,

135:44

Speaker A

который говорит, что нужно найти остаток отделения левого на правое. Соответственно, мы будем сейчас искать остаток отделения 11 на3. Выводим на экран и запускаем программу. Остаток отделения два. Так же, как мы с вами разбирали, вот можете чуть назад перемотать, посмотреть, почему именно

136:03

Speaker A

два. Давайте ещё посмотрим, что мы можем делать с текстом. Допустим, у нас тут вот лежит Hello. Что мы можем сделать с этой переменной помимо того, чтобы вывести на экран? Мы можем тоже к тексту прибавлять текст. Вычитать не можем,

136:17

Speaker A

делить не можем, умножать тоже не можем, потому что, ну, непонятно, что такое умножить текст на текст, да, или что такое поделить текст на текст. А вот прибавить текст и можем. Просто получится конкатинация строк, так называемая. Что это значит? Сейчас

136:32

Speaker A

покажу. То есть текст, мы можем текст плюс world, да? И давайте выведем значение переменной текст на экран FMT Printl. Кстати, ещё замечание. Видите, у меня сейчас не подключен ящик инструментов FMT. Пакет FMT я не импортировал, забыл, но язык

136:56

Speaker A

программирования GLENG умеет помогать мне в этом и умеет импортировать сам пакеты, которые мы с вами не доимпортировали. Происходит это в момент сохранения файла. Вот я нажимаю сохранить файл.

137:09

Speaker A

Оп. И ящик с инструментами FMT сам был взят. Почему? Потому что язык программирования увидел, что я хочу заиспользовать этот ящик инструментов, я хочу заиспользовать оттуда инструмент, но сам ящик я как бы хочу использовать, но взять я его забыл. Язык

137:24

Speaker A

программирования за нас его берёт. Давайте выведем на экран результат нашей программы. Увидим Hello World. Да, мы вывели одну переменную. Тут два слова.

137:34

Speaker A

Почему? Потому что мы к одному слову прибавили второе слово. Ну и тут я ещё пробел поставил, чтобы между ними тут тоже был пробел. Соответственно, я могу так конконтинировать строки, ну, сколько захочу. Есть ещё несколько вещей про переменные, которые нам хорошо бы знать.

137:49

Speaker A

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

138:06

Speaker A

предыдущих уроках мы посмотрели, узнали, что это такое, и сейчас мы уже не впадаем в состояние тряски. О чём я говорю? Первое, о чём я хочу поговорить - это про виды создания переменной. До этого мы с вами всегда, когда создавали

138:21

Speaker A

переменную, мы пользовались коротким типом записи. Почему он короткий? Потому что мы не пишем конкретный тип переменной, которую мы создаём. Тип переменной, который мы создаём, определяется по значению, которое стоит справа от знака двоеточие равно. То есть вот мы написали слева название

138:38

Speaker A

переменной, потом двоеточее равно, потом значение, которое в эту переменную нужно положить. И у нас язык программирования видит, что справа двоеточе равно стоит пть. Ну значит, это целое число. Значит переменную скор нужно создать типа integer, то есть integer целое число.

138:52

Speaker A

О'кей? Это короткий тип записи. То же самое было с текстом, например, да? Вот мы любую переменную там, назову её S.

138:58

Speaker A

Если я кладу в неё строку, то язык программирования видит, что справа от знака двоеточие равно стоит строка, и тогда переменная S будет типа strтринг автоматически выведена. Хорошо, какие есть ещё виды создания переменных? Ну, есть длинный тип записи. Давайте

139:12

Speaker A

посмотрим, как выглядит длинный тип записи. Ну, заместо переменной скор я буду создавать переменную number, а заместо переменной s переменную текст.

139:19

Speaker A

Как выглядит длинный тип записи? Для начала нужно написать ключевое слово, то есть variable, да, переменная с английского. Потом нужно написать название переменной. Ну вот number.

139:29

Speaker A

После этого пишем конкретный тип, создаваемой переменной. Ну вот, например, integer. И потом кладём туда какое-то значение. По сути то, что я написал, вот это вот war number in = 10 - это то же самое, что в четвёртой строчке, когда я создал переменную скор

139:44

Speaker A

и клал в неё пять. Только тут я создаю переменную numberр и кладу в неё 10.

139:49

Speaker A

Просто это длинный тип записи, когда я могу указать конкретный тип переменной, которую я хочу создать. Для чего нам это может быть нужно? Ну, если честно, пока что ни для чего. Пока мы ещё не изучили темы, которые бы могли стать основой в

140:04

Speaker A

объяснении тому, для чего вообще вот эта длинная запись нам нужна. Пока просто воспримем это как такой элемент общего развития, что мы можем создавать переменные и через короткую запись, и через длинную запись. через короткую запись, когда мы создаём, мы должны

140:18

Speaker A

сразу же указать переменной значение, которое в ней должно лежать. То есть мы не можем вот так вот сделать, да? У нас как бы переменный скор какое-то значение должно быть положено в неё там 10 или там строка какая-нибудь, что угодно. И

140:30

Speaker A

на основе этого значения будет выведен конкретный тип переменной и присвоен этой самой переменной. Когда же мы с вами указываем длинный тип записи, мы можем создать переменную, но при этом сразу не присваивать ей никакого значения. Да, ну давайте ещё вот длинную

140:45

Speaker A

запись применим на строковые переменной. Опять же ключевое слово, после этого название переменной, после этого тип переменной и значение, которое мы туда хотим положить. Повторюсь, вот это вот то же самое, что и это. То есть мы просто создаём переменную типа string,

141:01

Speaker A

кладём в неё high и называем как-то вот как мы хотим. И тут то же самое. Создаём переменну типа string и кладём в неё hello. Но это длинный тип записи, а это короткий. При коротком типе записи мы сразу же должны в переменную положить

141:12

Speaker A

какое-то значение, иначе у нас программа не запустится. При длинном же типе записи мы можем не указывать значения при создании. То есть у нас просто создастся переменная и в ней будет какое-то значение. Какое? ВН есть такое понятие, как значение по умолчанию. Ну

141:29

Speaker A

давайте я сотру переменные с коротким типом записи. Мы их как бы проходили. Пока давайте посмотрим на переменные длинного типа записи. То есть, если мы при создании переменных с длинным типом записи не будем туда класть никакое значение, то этим самым переменным

141:43

Speaker A

присвоится значение по умолчанию. Что такое значение по умолчанию? Для разных типов это разные значения. Например, для интеджера значение по умолчанию - это ноль. Для строки значение по умолчанию - это пустая строка. То есть давайте посмотрим, как это выглядит. Number я хочу вывести и вывожу

142:02

Speaker A

number. [аплодисменты] Ну и текст. Теперь хочу запустить программу и вижу, что у меня numberр ноль, а текст, ну, ничего не выявилось, потому что пустая строка у нас. Пустая строка выглядит следующим образом. То есть вот это пустая строка. Строка, в

142:22

Speaker A

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

142:37

Speaker A

создать эти переменные, вывести их на экран, и только после этого я в них перезапишу значение. В Num number я положу 15, а в текст я положу Hello World. После этого ещё раз выведу эти переменные на экран. Сохраняю, запускаю и вижу, что сначала вывелась

142:56

Speaker A

ноль и пустая строка. После этого 15 и Hello World. То есть благодаря вот этому длинному типу запись я могу переменную сначала создать, а только потом в неё положить какое-то значение. Пока что для нас это плюс-минус бесполезная функциональность. Мы не знаем, как это

143:10

Speaker A

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

143:21

Speaker A

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

143:34

Speaker A

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

143:45

Speaker A

В принципе, всё создали переменную типа int, положили туда 19, а могли не класть, потому что у нас длинный тип записи. Просто для общего развития. В будущем мы с этим столкнёмся, но сейчас мы просто воспримем как данность, что существует вот такой вот длинный формат

143:59

Speaker A

создания переменных. Давайте ещё посмотрим назначению по умолчанию для других типов. Вот у нас в number. Так как мы при создании не кладём туда никакого значения, да, то есть мы после знака равно ничего не пишем, как и сам знак равно, то в number положится

144:13

Speaker A

значение по умолчанию типа int, в текст положится значение по умолчанию типа string. Давайте посмотрим на значение по умолчанию типа дробное число, дробь флот. И как мы видим, у флота нету обычного типа, как у in. У флот есть только флот 32 и флот 64. Что это

144:29

Speaker A

значит? Это количество занимаемой оперативной памяти. То есть, чем больше мы с вами оперативной памяти занимаем, тем больше точность у нашего дробного числа, тем больше знаков после запятой мы с вами можем корректно хранить, обрабатывать с наименьшей долей ошибки.

144:44

Speaker A

Ну, вообще-то говоря, в Голенге практически всегда используется флот 64. Даже когда мы с вами просто создаём переменную при помощи короткого типа записи, если на неё навести, увидим, что автоматически присвоен был тип flat именно 64, потому что Flot 32 уже редко

144:59

Speaker A

где используется и практически везде используется Flot 64. Даже повторюсь, язык программирования автоматически выбирает именно этот тип. Ну давайте его и будем использовать. И посмотрим на значение по умолчанию для булиана.

145:12

Speaker A

Назову переменную булин и тип бул у неё будет. Давайте выведу всё это на экран.

145:18

Speaker A

[аплодисменты] number текст дробь и булин сохраняю, запускаю. Ну и видим, что для numberр, то есть для интеджера значение по умолчанию - это ноль. Для строки значение по умолчанию - это пустая строка. Для дробного числа значение по умолчанию тоже ноль. И для були на

145:42

Speaker A

значение по умолчанию false. То есть, повторюсь, значение по умолчанию - это то значение, которое присваивается переменной, если мы никакого значения сами, как программисты не указали. То есть просто переменную создали благодаря длинному типу записи, но значение туда никакое класть не стали. И поэтому язык

146:00

Speaker A

программирования положил в эти переменные значения по умолчанию. Также мы с вами проходили операции над переменными. Давайте я оставлю пока только целочисленную переменную и вспомним, какие же операции мы над ней умели проводить. Присвои сразу же значение какое-то, например, 20. И могу оставить просто короткую

146:20

Speaker A

запись, потому что в данном случае нам никакого смысла использовать длинную запись нету. Поэтому оставлю лишь короткую запись создания переменной number. Number и двоеточе равно 20. То есть при помощи короткой записи сразу же создал переменную number и автоматически для неё язык программирования сам вывел

146:37

Speaker A

нужный тип, основываясь на значении, которая стоит справа от знака двоеточее равно. О'кей. Вспоминаем, что мы проходили арифметические операции с нашей переменной целочисленной. Какие?

146:47

Speaker A

Ну, например, сложение. То есть мы numberр можем написать равно numberр + 5. У нас изначально numberр был равен двадцати. Потом мы в переменную number записали результат следующего выражения: number + 5. То есть 20 + 5 - это 25. И

147:02

Speaker A

25 положилась обратно в number. После чего мы можем вывести эту переменную на экран. Сохраняю файл, запускаю и вижу, что действительно в numberложилось 25. Но это длинная запись изменения значения какой-то переменной.

147:18

Speaker A

Мы, если какую-то переменную хотим изменить на какое-то число, мы можем воспользоваться короткой записью. Вот это я не пишу и пишу плюс равно. Что это значит? Смысл остался абсолютно тот же самый. Я к переменной number прибавил пятёрку. Просто использовал для этого

147:36

Speaker A

недлинную запись следующего характера, когда мы в переменную, которая стоит слева от знака равно, записываем результат выражения, которой стоит справа от знака равно.

147:45

Speaker A

Справа знака равно у нас стоит number + 5, то есть 20 + 5 25. И мы 25 пишем в переменную number. Это длинная запись.

147:53

Speaker A

Можем воспользоваться короткой. Просто number плюс равно и значение, которое мы хотим прибавить к этой переменной.

147:59

Speaker A

Давайте запустим. И как мы видим, результат остался тем же самым. То есть, если тут плюс равно 10, то вот будет 30.

148:05

Speaker A

Благодаря короткой записи мы можем изменять значение переменной без необходимости писать её несколько раз. Вот это была бы длинная запись. А так можно коротенько записью воспользоваться. И всё. Такая же короткая запись есть для других операций, например, для вычитания. Для

148:23

Speaker A

того, чтобы воспользоваться короткой записью вычитания, вместо плюс равно, нужно написать минус равно. Всё. Что это значит? Это значит, что я от переменной number отниму 10. Длинная же запись выглядела бы следующим образом. Number равно number - 10. То есть я в

148:38

Speaker A

переменную number хочу положить результат выражения, который стоит справа знака равно. А тут у меня number - 10, то есть 20 - 10, тут у меня 10. Я обратно эту десятку записываю в number.

148:49

Speaker A

Ну давайте сохраним, посмотрим. Да, результат 10. То есть если бы тут у нас было 25, например, то оставалось бы 15, потому что 25 - 10 - это 15. А теперь посмотрим на короткую запись. Минус равно. Всё. Теперь я от

149:06

Speaker A

просто вычту 10. Результат тот же самый, просто короткая запись. Ну, то же самое у нас и с умножением, и с делением. То есть вот набор умножить равно 10. То есть 25 я умножу на 10, получу 250. Всё верно. Теперь 25 я поделю на

149:20

Speaker A

10 и получу два. Ну, потому что у нас целочисленное деление. Если бы в намре у нас лежала дробь, то результат у нас был бы дробный. То есть 2 с 12. Ну, точно так же с дробями мы можем умножить равно

149:31

Speaker A

писать делить равно минус равно плюс равно. И так как у нас мы знаем, что мы умеем складывать строки, то есть, например, в текст я положу hello, потом текст равно текст плюс world и выведу это на экран. Текст у меня получился Hello

149:49

Speaker A

World, потому что изначально я в переменную текст положил hello и потом в переменную текст перезаписал следующее значение. Перезаписал то, что стоит справа от знака равно. Справа от знака равно у меня текст плюс world, то есть hello + world. Никаких пробелов тут нет.

150:05

Speaker A

В итоге получилось Hello World. Но я то же самое мог сделать и с помощью короткой записи. То есть текст плюс равно World. Всё, я создал переменнуй текст и добавил в неё какое-то значение.

150:16

Speaker A

Соответственно, результат остался тем же самым. Таким образом, мы с вами изучили короткую запись арифметических операций над переменными. То есть, допустим, я хочу там прибавить к numberр пятёрку, и мне вместо того, чтобы писать number равно numberр п, я могу написать

150:32

Speaker A

просто number плюс равно 5. Всё, результат будет тот же самый. Но есть ещё одно упрощение. Вот это упрощение над упрощением, когда мы хотим с вами изменить какое-то число на единицу, как у нас был счёт, например, да, скоe. И мы хотим счёту прибавить

150:51

Speaker A

единицу. Вот, например, скоore +1, да? Давайте я выведу его, запускаю и вижу скорше. То есть изначально было пять, потом 5 + 1, 6 вывелшесть. Всё верно. Мы помним, что у нас есть короткая запись для этого. То есть мы можем тут стереть и написать

151:07

Speaker A

score плюс равно 1. И будет то же самое. Но есть ещё более короткая запись для вот таких вот изменений на единицу.

151:16

Speaker A

Просто плюс-плюс всё. То есть это то же самое, что и score равно score + 1. То есть просто короткая запись для увеличения числа на единицу. Потому что в языках программирования очень часто мы встречаемся с тем, что нужно какую-то

151:32

Speaker A

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

151:46

Speaker A

Это называется инкремент. То есть просто такое название инкремент, что означает, что мы увеличиваем значение переменной на единицу. Ну давайте я тут поставлю, например, семь инкремент, то есть тут должно стать восемь и выведу на экран.

151:59

Speaker A

Да, всё верно, восьмёрочка. То же самое есть для уменьшения на единицу. То есть у нас вот скор равно скор - 1, да? Это у нас сейчас будет 6, потому что было 7. 7 - 1 6. Можем написать просто короткую

152:13

Speaker A

запись. Скор - равно 1 тоже будет. Но можем написать укороченную запись укороченной записи скор минус минус.

152:20

Speaker A

Всё, это называется декремент. Это инкремент, то есть увеличение, а это декремент, то есть уменьшение. Такие термины достаточно распространённые в программировании, поэтому хорошо бы их запомнить. Это инкремент - это декремент. То есть, что такое инкремент? Это увеличение чиселки на единицу, увеличение нашей переменной

152:40

Speaker A

на единицу. То есть это укороченная запись от вот этой вот укороченной записи, а это укороченная запись от вот этой вот записи. То есть понимаем, что это всё одно и то же, просто для удобства мы имеем укороченные записи. Это полезно

152:56

Speaker A

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

153:11

Speaker A

узнали, что это какая-то ячейка, какая-то область в оперативной памяти, в которой лежит какое-то значение, значение определённого типа. То есть есть у нас целые числа, есть у нас строки, есть у нас дробные числа и есть у нас бульон. Также узнали, что у нас

153:26

Speaker A

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

153:38

Speaker A

пользоваться коротким типом записи, но вдруг, если встретим этот длинный тип, то будем к нему готовы. Мы узнали, что у нас есть возможность применять арифметические операции над переменными.

153:48

Speaker A

То есть можем складывать, можем делить, можем умножать. И увидели, как именно это делается, плюс рассмотрели короткие виды записи некоторых арифметических операций.

153:59

Speaker A

[музыка] Следующая тема у нас на очереди - это условия и условные ветвления. Мы посмотрим, что это такое, для чего вообще нужно и как это используется. Для начала давайте вернёмся к нашей игре Flppy Bird и посмотрим, в чём вообще её

154:15

Speaker A

суть. Вспомним. То есть мы нажимаем на экран. Благодаря этому у нас подбрасывается наша птичка, и мы можем пролетать через трубы. За каждую трубу, которую мы с вами преодолели, нам начисляется одно очко. И наш общий счёт показывается верхней части экрана. То

154:30

Speaker A

есть, сколько труб мы с вами преодолели, такой у нас и счёт. То есть счёт с английского это, я напоминаю скор. И с точки зрения языка программирования вот этот вот счёт, который нам показывается вверху экрана - это, по сути, какая-то

154:43

Speaker A

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

154:59

Speaker A

есть вот у нас есть график наш очков. Давайте я его даже подпишу как скор. Вот наш график счёта. Если игрок набрал больше десяти очков, то есть больше десяти - это 11 и до бесконечности. То есть всё, что попадает

155:16

Speaker A

в зелёную зону, тут мы говорим игроку, что он красавчик. Иначе если игрок не смог попасть в эту зелёную зону, то нам нужно ему сказать, что необходимо ещё многому научиться. Ещё необходимо подтянуть скилуху для того, чтобы ты смог называться красавчиком. То есть мы

155:33

Speaker A

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

155:47

Speaker A

если наш счёт больше десяти, ну, счёт - это по-английски скор, тогда мы говорим игроку, что ты [аплодисменты] красавчик. Иначе, если у игрока счёт не больше десяти, да, то есть если он не попал в эту зелёную зону, тогда мы ему

156:04

Speaker A

скажем, что тебе нужно ещё многому научиться. То есть мы будем смотреть на наш счёт. А счёт у нас в программе представлен как переменная скор, если вы помните из предыдущего урока. Мы должны посмотреть на наш счёт и понять, он

156:22

Speaker A

больше десяти. Если да, тогда игрок красавчик. Если нет, тогда тебе нужно ещё многому научиться. Я надеюсь, в общих чертах понятна идея. То есть у нас есть задание, что если игрок набрал больше десяти очков в конце игры, то нужно ему сказать, что он красавчик. Да,

156:43

Speaker A

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

156:57

Speaker A

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

157:15

Speaker A

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

157:29

Speaker A

скор, в которую положу целочисленное значение пять. Вот переменная скор у нас типа int. Ну, сейчас он жалуется, что мы её создали и нигде не использовали. Ну, сейчас будем использовать. Теперь нам нужно каким-то образом вывести. Ты красавчик. Ну, будем выводить игроку как

157:42

Speaker A

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

158:00

Speaker A

попал под условие, счёт больше десяти. [аплодисменты] Если мы с вами вот так вот напишем, то, во-первых, программа в принципе не запустится, потому что мы создаём переменную скор, но мы с ней ничего не делаем. А во-вторых, если бы у нас не

158:19

Speaker A

было переменной скор, то наша программа просто бы выводила: "Ты красавчик, тебе нужно ещё многому научиться". То есть обычное выполнение программы сверху вниз. И непонятно, как нам выводить одно, если у нас счёт больше десяти, и как нам выводить другое, если счёт

158:37

Speaker A

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

158:54

Speaker A

как бы идёт просто сверху вниз, да. Вот там главный кусок кода. Ну, функция вот эта наша [аплодисменты] функз выполнение кода. Но когда мы с вами будем опираться на наш скор, у нас начнётся ветвление. То есть самое настоящее ветвление, как вот ветки у

159:13

Speaker A

дерева. у нас программа будет идти уже не сверху вниз, у нас появится какое-то условие, которое будет регулировать то, что нам будет выводиться на экран, потому что без этого условия у нас программа идёт просто сверху вниз и выводится всё, что попало. Нету вот этой

159:31

Speaker A

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

159:48

Speaker A

переменная score. И теперь я напишу код, потом объясню, что я вообще написал. Если скор больше десяти, тогда выводим ты красавчик.

160:03

Speaker A

Иначе выводим. Тебе нужно ещё многому научиться. Что тут вообще произошло? Я использовал условное витвление в своей программе. До восьмой строчки программа выполнялась просто сверху вниз. Но в восьмой строке я задал условное ветвление. Я взял и описал вот этот вот

160:24

Speaker A

кусок кода, который мы с вами схематически изображали. Что тут вообще произошло? If с английского переводится как если, переводится как иначе. Так что же я в итоге написал? Я написал, что если счёт больше десяти, тогда выполни вот этот вот кусок кода. Да, помните,

160:43

Speaker A

как понять, где кусок кода начинается, а где кусок кода заканчивается. Нам нужно просто навести на какую-нибудь скобочку, и нам сразу же редактор кода подсветит в скобочку, которая закрывающая. Вот, допустим, у нас Funk main, главный кусок кода. Мы нажимаем на открывающую вот эту

161:01

Speaker A

вот скобочку, и нам автоматически подсвечивается закрывающая. Вот она в пятнадцатой строчке. И наоборот, если я нажму на закрывающую, то мне автоматически подсвечивается открывающая. То есть нам таким образом становится понятно, где блок кода, который ограничивается главной функцией main. Точно так же с условным

161:19

Speaker A

ветвлением. Мы можем нажать на открывающую скобочку, и нам редактор кода сразу подсветит закрывающую скобочку. И наоборот, можем нажать на закрывающую скобочку, редактор кода подсветит открывающую. То есть вот это какой-то отдельный кусок кода. И после Элса, то, что идёт - это какой-то

161:36

Speaker A

отдельный кусок кода. Элса - это, я напоминаю иначе. Так вот, я написал условное ветвление, которое заключается в следующем. Я сказал языку программирования: "Если счёт больше 10, тогда выполни вот этот вот кусок кода, который я выделил". Иначе, что значит

161:56

Speaker A

иначе? Это если условие, которое написано в ифе, оно даёт нет, то есть даёт ложь. Что это значит? Это то, что мы с вами на схеме обсуждали. Если счёт больше десяти, нет, то есть, допустим, да, вот игрок попал куда-то в красную

162:12

Speaker A

зону, счёт больше десяти? Нет, и вот это самое нет - это эса. То есть иначе выполни вот этот вот кусок кода. Если счёт больше десяти, иначе выполни вот этот вот кусок кода. Это условное ветвление, которое нам очень подходит

162:30

Speaker A

для решения вот этой вот самой задачи, которую нам поставил начальник. Давайте сохраним файл и запустим программу. Посмотрим, что вообще тут происходит. Давайте. Go run main go. Тебе нужно ещё многому научиться. Вывелась. Тебе нужно ещё многому научиться. Почему? Давайте

162:49

Speaker A

подумаем. Мы берём, идём сверху вниз. Ну, пакет главный. Берём ящик инструментов FMТа, главный кусок кодаме main, вот он где начинается, где заканчивается, и создаём переменную скоe. Она у нас равна пяти. Потом в восьмой строчке у нас начинается условное ветвление, которое смотрит на

163:06

Speaker A

вот это вот выражение: счёт больше десяти. Если счёт больше десяти, а у нас счёт пять, 5>ше 10, нет, выполнился блок кода Элса, потому что пять не больше десяти. Ещё раз. Пять. Мы смотрим скор.

163:23

Speaker A

В скор лежит пть 5 больше 10? Нет. Мы просили язык программирования выполнить блок кода, в котором печатается ты, красавчик, если счёт больше десяти. Но у нас счёт не больше десяти. И выполнился кусок кода, который призван выполняться, если условие у нас ложное. То есть

163:45

Speaker A

условие счёт больше десяти ложное. Почему? Потому что 5 не больше 10. Поэтому выполнилась Элса. А теперь давайте посмотрим, что будет, если мы поставим другое число. Например, сюда 15. Да, сохраняем и запускаем программу.

164:02

Speaker A

Ты красавчик, вывелась. Знаете, почему? Давайте посмотрим. У нас счёт равен пятнадцати. И мы смотрим. Если счёт больше 10ти, тогда выведет ты красавчик.

164:12

Speaker A

А у нас счёт больше десяти, потому что 15 > 10. Соответственно, мы набрали с вами 15. На вот этой вот схемке мы вообще ушли вон далеко в зелёную зону туда. Мы красавчики. И как бы 15 больше десяти, да? Вывелась. Ты красавчик.

164:28

Speaker A

Собственно, вот как работает условное ветвление в нашей программе. И условия. Мы с вами можем смотреть на значение каких-то переменных. Мы можем ставить условия, при которых выполнится какой-то кусок кода. То есть нам нужно не как у нас было изначально, что просто всё

164:46

Speaker A

выводится как бы не пойми как, просто сверху вниз программа выполняется и выводится вообще всё, что в ней написано. Да, ты красавчик, тебе нужно многому научиться, какая-то фигня. Мы не можем сразу две этих надписи вывести, потому что нам начальник сказал, что мы

165:02

Speaker A

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

165:18

Speaker A

тупо весь написанный код, а выполнялся только тот код, который нам нужен, исходя из условия. Можете просто поиграться, поставить разный счёт, например, один. Запускаем. Тебе нужно ещё многому научиться, да? Потому что, ну, один - это совсем мало. Один - это

165:35

Speaker A

вот мы вот вот столько вот набрали. Вот мы здесь, а нам нужно больше десяти. Ну вот давайте восемь попробуем, да? Если у нас счёт будет восьми равен, запускаем программу. Ну тебе нужно многому научиться всё ещё, потому что у нас, ну,

165:49

Speaker A

типа восемь. А нам, чтобы быть красавчиками, нужно вот в зелёную зону попасть. Давайте попробуем 10 ввести.

165:55

Speaker A

Что будет? 10. Сохраняю, запускаю. Тебе нужно ещё многому научиться. Ну, потому что 10 у нас не больше 10. 10 у нас равно 10, да? Но 10 > 10? Нет. То есть 10 - это 10. Вот у нас тут 10 больше десяти. У нас вот тут

166:16

Speaker A

вот все наши цифры и числа. А это просто 10. Оно не больше десяти. Оно равно 10сяти, но не больше. Вот тут вот всё, что больше. Поэтому даже если мы набрали счёт 10, мы всё равно остались в красной зоне. Мы всё равно ещё не красавчики, но

166:33

Speaker A

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

166:52

Speaker A

дальше программа продолжит своё выполнение. Как это будет выглядеть? Допустим, мы тут напишем ещё счёт игрока, дополнительно ему подсветим, если он забыл, и скажем игроку спасибо за то, что пользуется нашей игрой, и пожелаем ему скорейшего [аплодисменты] возвращения. Вот. То есть у нас что

167:21

Speaker A

происходит в нашем главном куске кода? Мы создаём переменную скор, в которую кладём целое число 10. Потом у нас программа начинает ветвиться. То есть тут у нас уже не просто сверху вниз идёт исполнение, потому что тогда бы у нас

167:35

Speaker A

вывелось и ты красавчик, и тебе нужно ещё многому научиться, а у нас начинается ветвление. Мы смотрим, если у нас скор больше десяти, тогда выполни вот эту вот часть ветвления. Иначе выполни вот эту вот часть ветвления. Но дальше программа опять пойдёт сверху

167:52

Speaker A

вниз без всякого ветвления, потому что тут мы никакого ветвления не указывали. Давайте запустим программу и увидим, что счёт у нас 10.

168:04

Speaker A

Поэтому у нас выполнился вот этот вот кусок кода, да, потому что 10 - это всё ещё в красной зоне. И потом мы продолжили своё выполнение сверху вниз, вывели счёт и поблагодарили игрока за игру. Если у нас счёт будет, например,

168:19

Speaker A

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

168:33

Speaker A

выражения, если счёт больше 10 был истинным, то есть счёт больше 10, да, тогда мы выполнили вот этот вот первый кусок кода и вывели бы на экран.

168:45

Speaker A

Ты красавчик. Если бы у нас счёт был, например, 5, 5 боше 10, 5 больше 10. Нет, тогда выводим.

168:55

Speaker A

Тебе нужно ещё многому научиться. Ну, у нас так бы и получилось. Пть. П 5 боше 10. Нет, тогда выводим то, что в блоке Элса. Тебе нужно ещё многому научиться.

169:08

Speaker A

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

169:27

Speaker A

это понравилось, всем пользователям это зашло, все поставили хорошие оценки нам в Play Markket, Web Store. И понял наш начальник, что нужно копать в эту сторону, чтобы ещё больше игроков завлечь в нашу игру. И принёс нам следующую задачку, которая очень похожа

169:44

Speaker A

на предыдущую, но с некоторым усложнением. Давайте посмотрим, что от нас теперь хочет начальник. Он нас, конечно же, похвалил, сказал: "Какие мы красавчики, как круто пользователям зашла наша фича". Но пришло время двигаться дальше. Давайте посмотрим, какая наша следующая задача. Если игрок

170:00

Speaker A

набрал больше десяти очков, то нужно сказать, что он красавчик. Ну хорошо, это, в принципе, очень похоже на то, что было раньше. Если игрок набрал больше пцати очков, то нужно сказать, что он мегакрасавчик. В этом то и отличие. До

170:14

Speaker A

этого у нас всё, что больше десяти - это всё красавчик. Но теперь у нас помимо зелёной зоны появилась ещё и синяя зона, которая больше пятнадцати. Всё, что больше пятнадцати - это синяя зона. Это мегакрасавчик. Ну, если у нас игрок в

170:31

Speaker A

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

170:50

Speaker A

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

171:04

Speaker A

выбирать. Нам будет дан счёт, и нам нужно будет выбирать, что именно вывести. Либо красавчик, либо мегакрасавчик, либо что нужно многому научиться. Давайте попробуем как-то схематически это представить. Повторюсь, схемы могут быть разные. С опытом вы научитесь наиболее эффективно использовать это условное ветвление.

171:26

Speaker A

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

171:42

Speaker A

откуда начинается выполнение нашей программы. И поехали. Вот программа выполняется сверху вниз, пока мы не встретим первое условное ветвление. Ну, значит, первое наше условное ветвление.

171:52

Speaker A

Если игрок набрал больше десяти очков, то нужно сказать, что он красавчик. Ну хорошо, давайте вот наше условие. Если счёт больше десяти, тогда скажем игроку, что он красавчик. То есть счёт больше десяти, да? Ну, значит, говорим: "Ты красавчик".

172:09

Speaker A

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

172:30

Speaker A

она будет работать для всех значений от нуля до 15. Но если вдруг, предположим, игрок набрал, ну, 20 очков, да, 20 очков, 20 больше 10, да, ты красавчик.

172:45

Speaker A

Но нам, если игрок попал в синюю зону, а если он набрал 20 очков, то он в синей зоне, нам нужно выводить ты мегакрасавчик. Как-то уже не клеится.

172:55

Speaker A

Давайте думать, что можно с этим сделать. Вот, допустим, мы проверили наше условие, что мы больше десяти, что игрок набрал больше 10ти очков. Это значит, что мы автоматически попадаем в одну из этих двух зон. То есть мы уже точно не в красной зоне, да,

173:12

Speaker A

потому что мы набрали больше десяти, мы уже в какой-то одной из этих двух зон. А как узнать, в какой именно? То есть тут тоже в этой зоне, да, если мы попали вот в зону больше десяти, тут тоже у нас

173:26

Speaker A

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

173:41

Speaker A

зоне мы находимся. Для этого берём ещё одно условие, ставим. Если счёт больше 15, что тут происходит? Мы начинаем наше выполнение и смотрим. Если счёт больше 10, да, получается, если счёт больше десяти, мы попадаем в какую-то одну из этих двух зон. И чтобы понять, в какую

174:03

Speaker A

именно, нам нужно ещё раз посмотреть на наш счёт. Он больше пятнадцати или нет? Если мы попали в эту зону и счёт больше пятнадцати, то мы попали в синюю зону.

174:15

Speaker A

Это значит, что мы мегакрасавчики. Так и запишем. Что тут случилось? Мы добавили ещё одно условное ветвление, да? То есть, если мы набрали больше десяти очков, смотрим, если нет, то есть, да, если мы оказались в красной зоне, если мы не набрали больше 10ти очков, мы

174:41

Speaker A

где-то тут, ну, значит, нам нужно ещё многому научиться. Если мы набрали больше десяти очков, тогда мы можем быть либо красавчиком, либо мегакрасавчиком.

174:53

Speaker A

Как понять, каким именно красавчиком мы являемся, если мы уже точно в этой зоне? Ну, нам нужно ещё раз проверить наш счёт, он больше пятнадцати или нет. Если мы в какой-то из этих двух зон и мы набрали больше пятнадцати, да, то есть

175:07

Speaker A

вот мы попали в синюю зону, значит мы мегакрасавчики. Ну, а если мы больше десяти, это условие выполняется, если мы больше 10ти, но при этом счёт будет у нас не больше пнадцати, больше десяти, но не больше пятнадцати, значит, мы в

175:26

Speaker A

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

175:50

Speaker A

что, в принципе, то она рабочая. Ну, возьмём, допустим, четыре. Вот мы набрали четыре. Начинаем нашу функцию.

175:57

Speaker A

Начинаем нашу программу из главной самой функции. Смотрим, мы набрали четыре. Если счёт больше 10ти, а у нас счёт 4, 4 больше 10. Нет, ну всё, значит нам выведется. Тебе нужно ещё многому научиться. Возьмём 13. Допустим, мы набрали 13. Начинается наша программа.

176:16

Speaker A

Если счёт больше 10, 13 > 10, да? Вот 13, а вот 10. 13 > 10. Значит, да?

176:25

Speaker A

Значит, попадаем вот в эту опять ещё одно условное ветвление. Тут смотрим. Если счёт больше 15, 13 > 15, нет. Вот 13, а вот 15. То есть, ну, 15 явно больше, чем 13. Нет. И мы попадаем в Ты красавчик. Просто ты красавчик. Теперь

176:44

Speaker A

возьмём число. Ну, допустим, 19. Функция main. Счёт больше 10. Счёт 19. 19

176:46

Speaker B

10, да? Счёт больше пятнадцати. Ну, 19

176:52

Speaker C

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

177:14

Speaker C

работает. Остаётся только её отразить на языке программирования. Давайте посмотрим, как это вообще может выглядеть с точки зрения языка программирования. Я таким образом использовал разделение экрана, чтобы наглядно было видно, как написанный код соотносится с нарисованной нами схемкой.

177:30

Speaker C

Ну давайте начнём опять писать код. Я удалю всё, что было, и сделаем нашу переменную скор опять, да? То есть у нас есть какой-то счёт. Ну пускай он будет там, не знаю, ну опять пять. Потом, если что, будем его менять. Смотрим на нашу

177:45

Speaker C

схему, и нам практически сразу в нашей программе нужно условное ветвление. Нам нужно проверить наш счёт, больше ли он десяти. Ну, давайте посмотрим. Если счёт больше десяти, тогда нам нужно сразу же проверить, больше ли счёт пятнадцати.

178:05

Speaker C

Как это выглядит? Если счёт больше десяти, да? То есть мы, да, мы попали в этот кусок кода, и в этом куске кода нам нужно ещё одно условное ветвление произвести. Ну, это нам не запрещено.

178:19

Speaker C

Так делать можно. Давайте это и сделаем. Если счёт больше 15, что тут произошло? Как это вообще выглядит? Мы начинаем нашу программу и согласно схеме сразу смотрим, больше ли мы десяти. Счёт больше десяти. Если да, то у нас ещё

178:37

Speaker C

одно условное ветвление сразу же должно быть. Но мы его и сделали. Если счёт больше десяти, тогда мы будем выполнять этот кусок кода. И тут сразу же ещё одно условное ветвление. И если счёт больше пнадцати, тогда ты мегакрасавчик. Вот

178:51

Speaker C

если счёт больше пятнадцати, тогда ты мегакрасавчик. Давайте это и выведем. Иначе, если у нас счёт не больше пдцати, тогда просто ты красавчик. Ну вот это нет, иначе это у нас Элсы.

179:15

Speaker C

[аплодисменты] И теперь мы описали с вами весь блок кода, который у нас, если счёт больше десяти. Теперь нужно описать, что если у нас счёт не больше десяти, да? Если нет, тогда просто тебе нужно ещё многому научиться. Я скопирую этот текст. И вот

179:34

Speaker C

наш блок кода, который отвечает за условное ветвление счёт больше 10. И здесь мы и пишем.

179:44

Speaker C

[аплодисменты] Иначе тебе нужно ещё многому научиться. Сохраняю программу. Давайте сейчас вообще посмотрим, что мы тут написали.

179:55

Speaker C

По сути, мы с вами имплементировали, а, реализовали представленную схему. Ещё раз пройдёмся сверху вниз. Вот наша функция main, да, и поехали. Выполнение нашей программы. То есть до условного ветвления наша программа выполняется прямолинейно. То есть просто поехали сверху вниз, создаём нашу переменную и

180:15

Speaker C

потом сталкиваемся с нашим ветвлением. То есть, если счёт больше десяти, тогда нам нужно проверить счёт больше пятнадцати. Но мы это и делаем. Если счёт больше десяти, тогда выполняем вот этот вот кусок кода, в котором первым делом проверяем счёт больше пятнадцати.

180:32

Speaker C

Соответственно, если у нас счёт больше десяти, значит, мы в какой-то вот этой вот зоне, да? То есть если счёт больше десяти, мы попали в этот блок кода.

180:40

Speaker C

Значит, мы в какой-то одной из этих двух зон, либо в зелёной, либо в синей. И нам нужно дополнительное условие, чтобы конкретно понять, в каком именно мы с вами промежутке, в зелёном или в синем.

180:53

Speaker C

И мы смотрим, если счёт больше пятнадцати, тогда мы с вами вот в синей зоне, потому что 16 и дальше это всё больше пятнадцати. Значит, мы мегакрасавчики. Это мы и выводим. Ты мегакрасавчик. Иначе ты красавчик.

181:07

Speaker C

Почему? Да, потому что мы изначально проверили, что мы больше десяти. Вот больше десяти, а потом дополнительно проверили, что мы больше пятнадцати. И если мы больше десяти, но не больше пятнадцати, значит, мы в зелёной зоне. То есть вот таким вот

181:25

Speaker C

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

181:42

Speaker C

значит, мы точно не в этом множестве, значит, мы где-то здесь. Потом вторым условным ветвлением мы с вами отсекаем второе множество. То есть мы находимся здесь. И если мы больше пятнадцати, тогда мы отсекаем зелёное множество и мы мегакрасавчики. Если мы меньше либо

181:59

Speaker C

равно 15, то есть мы не больше пятнадцати, тогда мы отсекаем синюю зону и попадаем в зелёную. И точно так же в самом первом условии, если мы с вами не больше десяти, тогда мы сразу же отсекли все эти множества и поняли, что мы

182:16

Speaker C

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

182:36

Speaker C

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

182:46

Speaker C

Вам с каждым разом будет всё проще и проще это делать. И потом вы, как водитель, у которого много лет стажа, не думает о переключении механической коробки передач и о рулёжке, о знаках дорожных. Это всё на автомате происходит. Также у вас будет

182:59

Speaker C

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

183:10

Speaker C

Без практики ничего не будет, поэтому очень нужно писать код своими руками. Это была лишь одна из возможных схем, которая бы решала поставленную задачу.

183:20

Speaker C

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

183:34

Speaker C

функция main. И программа линейно выполняется до момента, пока мы не начнём с вами прописывать условное ветвление. Я, как человек с некоторым опытом в программировании сразу вижу, что можно написать код более элегантно, чем он написан благодаря вот такой схеме. То есть, ещё раз посмотрим на вот

183:55

Speaker C

такую схему. У нас тут есть двойная вложенность. Что это значит? Это значит, что у нас в куске кода ещё другие куски кода. В принципе, количество вложенности можно посмотреть по количеству табов. То есть вот раздва, тут даже 1 2 3. То есть вообще

184:13

Speaker C

тройная вложенность. И на самом деле с точки зрения программистов, чем больше вот этой самой вложенности, тем сложнее читать код. Потому что, ну, предположим, у нас бы тут ещё какое-нибудь условное витвление было, например, скор там больше пся и тут ещё какой-нибудь, если

184:30

Speaker C

скор больше 100. И уже становится вообще сложно читать этот код, потому что очень большая степень вложенности. И с опытом вы начнёте это чувствовать, что чем меньше этой самой вложенности, тем лучше. Но просто понимание того, как написать код, чтобы было меньше

184:48

Speaker C

вложенности, оно приходит с опытом. Поэтому напоминаю в который раз, что необходима практика. Постоянно всё, что мы делаем, необходимо практиковать своими руками, необходимо пытаться самому это написать. И я уже, как человек с некоторым опытом в программировании, я могу немножко

185:03

Speaker C

предвидеть наперёд, как будет выглядеть код благодаря нашим схемам. И поэтому я сейчас сделаю точно такую же схему. Она будет выполнять ровно те же самые задачи. Она будет нам находить область, в которую попал игрок, набрав некоторое количество очков. Но с точки зрения

185:20

Speaker C

написания кода это будет выглядеть немножко по-другому. Давайте посмотрим. Я сразу же вижу, что мы можем начать не с проверки скор больше десяти. Можем начать с проверки скор больше пятнадцати. Давайте первым делом это сделаем. если скор больше пятнадцати. И

185:36

Speaker C

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

185:50

Speaker C

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

186:01

Speaker C

Ну, давайте я это нарисую схематически. То есть, если скор больше пятнадцати, да, это значит, что ты мега красавчик. Ну, если нет, да, давайте посмотрим, что будет, если у нас всё-таки скор не больше пятнадцати. Если нет, тогда мы в какой-то одной из этих

186:23

Speaker C

двух областей. То есть, если скор больше 15ти, мы по-любому вот здесь. Иначе, ну, нам ничего не остаётся, значит, мы где-то тут. Как узнать, в какой именно мы области оказались? Ну, то есть нам нужно понять, вообще скор он больше

186:37

Speaker C

десяти или меньше десяти, да? То есть мы вот скор проверили, что он больше пятнадцати. Если да, то мы попали в синюю зону. Если нет, значит, мы в какой-то одной из этих двух зон. И тут нужно просто проверить, что скор больше

186:50

Speaker C

десяти. Если скор будет больше десяти, значит, мы по-любому вот в зелёной зоне. Ну, если меньше, значит, понятное дело, в красной. Если меньше либо равно 10ти, значит, мы в красной зоне. Если больше 10ти, значит, мы в зелёную зону попали.

187:03

Speaker C

Пишем, если скор больше 10. Ну, соответственно, ещё раз. То есть идём, наша программа начинает линейное выполнение и потом приступаем к первому условному ветвлению. И смотрим, если скор больше пятнадцати, тогда мы сразу же в синей зоне. Если да, значит мы

187:22

Speaker C

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

187:32

Speaker C

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

187:38

Speaker C

Иначе, если скор не больше пятнадцати, а что вообще значит не больше пятнадцати? Это значит либо равно пятнадцати, либо меньше пятнадцати. То есть, если больше пятнадцати - это эта зона. Если не больше пятнадцати - это значит меньше либо равно 15. То есть мы в этой зоне,

187:56

Speaker C

получается, мы здесь и проверяем, если скор больше 10ти, то есть мы уже благодаря этому условию поняли, что скорчно будет меньше либо равен пятнадцати. Потому что если бы скор был больше пятнадцати, мы бы сразу закончили своё выполнение на ты мегакрасавчик. Но

188:11

Speaker C

нет, мы перешли в секцию нет. Это значит, что скор меньше либо равен пятнадцати. И мы уже в рамках вот этих вот промежутков смотрим. Если скор больше десяти, значит, мы точно вот здесь вот. Значит, мы попали в зелёную зону, значит мы просто

188:26

Speaker C

красавчики. Тут да и ты красавчик. Ну и, соответственно, если нет, то получается, что мы вообще в красной зоне. Почему? Потому что мы проверили, скор больше пятнадцати. Нет. Значит, мы где-то тут.

188:47

Speaker C

Скор больше десяти? Нет. То есть, значит, мы однозначно попали в красную зону. И тут можем написать: "Тебе нужно ещё многому научиться".

189:01

Speaker C

Вот если посмотреть чисто схематически, можно заметить, что две нарисованные схемы, они симметричны, потому что у нас есть какой-то корневой элемент, из него мы начинаем условное ветвление.

189:17

Speaker C

Условное ветвление даёт нам один ответ сразу и порождает ещё одно условное ветвление. И тут точно так же условное ветвление даёт один ответ сразу, либо порождает ещё одно условное ветвление. И даже чисто на вид эти две схемы, они симметричны. Но с точки зрения кода

189:33

Speaker C

схема, которую мы написали только что, которую мы написали второй, она будет выглядеть более красиво. Сейчас я покажу, как это выглядит. Вот я опять наполам разделил экран. Вот наша старая схема, да, давайте я её подпишу и вот стрелочку вот такую вот сделаю. Что это

189:49

Speaker C

старая у нас схема? И есть у нас новая схема. Вот давайте посмотрим ещё раз, что у нас было по старой схеме, как у нас выглядел код. У нас была вложенность 1 2 3. У нас была тройная вложенность. И

190:01

Speaker C

в целом можете посмотреть, что код из-за этой самой вложенности выглядит довольно-таки запутанным. У нас условия, а в нём внутри ещё какое-то условие.

190:10

Speaker C

Теперь давайте посмотрим, как же код будет выглядеть с новой схемой. Для этого я старый код удалять не буду.

190:16

Speaker C

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

190:26

Speaker C

Что я имею в виду? Допустим, у нас в самом начале будет какой-то вывод на экран. Ну, Hello World, например, наш знакомый. Сохраняем программу, запускаем и видим, что у нас вначале Hello World. Ну, потом тебе нужно многому научиться, потому что у нас скор

190:44

Speaker C

равно пять. Пять больше десяти нет. Значит, вот тебе нужно многому научиться. Ну, это то, что мы до этого писали. Вот. Hello world. А теперь смотрите, я пишу в начале этой строчки два слэша. 1 2 сохраняю, запускаю и уже

190:59

Speaker C

никакого hхвор world воода не выводится. Почему? Потому что я этот код закомментировал. Что это значит? Это значит, что я оставил этот код в нашем файле с кодом, но при этом сказал языку программирования что пожалуйста вот эту строчку не нужно выполнять. Она мне

191:14

Speaker C

нужна просто как комментарий. Для чего ещё используются комментарии помимо того, чтобы спрятать и не использовать код и при этом его не удалять?

191:22

Speaker C

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

191:40

Speaker C

который будет идти после комментариев. Ну вот тут вот можно написать, что это условное видовление для определения промежутка, в который попал игрок. Всё.

191:57

Speaker C

И эта строчка, она никак не помешает языку программирования и нашей программе выполниться, потому что это закомментированная строчка, она, в принципе, не будет выполняться, она не будет преобразовываться ни в какие команды там для процессора. Это просто обычный комментарий.

192:11

Speaker C

как бы пометка такая. Ну давайте ещё раз запущу программу, увидим, что она работает. У нас не выводится Hello World, потому что мы закомментировали этот код. И у нас не выводится и никак не ломает вот этот наш комментарий программы, потому что это тоже просто

192:24

Speaker C

комментарий. Если мы сотрём эти два слэша, то увидим, что у нас сразу же ошибка. Если попробую программу запустить, нам скажут, что вот на девятой строчке ошибка синтаксиса. Да, вот девятая строчка, ошибка синтаксиса.

192:36

Speaker C

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

192:49

Speaker C

комментарий. Комментарии бывают однострочные, бывают многосрочные. Что такое многосрочный комментарий? Допустим, у меня есть три вывода на экран. Hello 1 Hello 2 и Hello 3. Давайте запустим программу, посмотрим, что она выводит. Вот. Hello 1, Hello 2, Hello 3. А потом я понял,

193:13

Speaker C

что я хочу этот код заставить не выполняться, но при этом не удалять его, чтобы я мог как бы смотреть на него и вообще запоминать, что я там до этого написал. Для этого я могу использовать односрочный комментарий, который мы с

193:26

Speaker C

вами уже изучили. Для этого мне придётся перед каждой строчкой ставить комментарии. 1 2 3. Сохраняем, запускаем. Видим, что это даже работает.

193:34

Speaker C

Но в чём тут неудобство? Это в том, что мне нужно каждую строчку отдельно комментировать. и потом, если что, отдельно раскомментировать. И это ещё терпимо, когда у нас три строчки, когда у нас строчек 30 или, может быть, мы целую большую функцию хотим

193:49

Speaker C

закомментировать, целый большой кусок кода, то там этих строчек может быть и 50, и 100, и 150. И вы прикиньте, так вот 150 раз комментировать каждую строчку, это неудобно. Поэтому придумали многосрочный комментарий, как он выглядит. Ставим слшзвёздочка и в конце ставим звёздочка

194:07

Speaker C

сш. Что тут произошло? Мы сказали языку программирования, что всё, что между слшзвёздочка и звёздочка с/ш - это комментарий, и поэтому этот код выполняться не будет. Давайте сохраним программу, запустим и увидим, что у нас тут не выводится никаких hello. Почему?

194:22

Speaker C

Потому что этот код закомментирован. То есть это из кода из команд компьютеру превратилось просто в пометку. Мы тут можем писать как бы что угодно. Мы можем написать: "Привет, меня зовут Вася. Я пришёл из школы, принёс тебе пирожков. Да, можем

194:42

Speaker C

сохранить, запустить. Увидим, что наша программа работает без ошибок. Но при этом мы оставили пометку, которую хотели, причём она многосрочная. Ставить однострочный комментарий или многосрочный можете на своё усмотрение.

194:54

Speaker C

Можете, в принципе, не комментировать свой код, но хорошей практикой является комментарии своего кода в каких-то сложных моментах или, в принципе, когда вы написали какой-то большой кусок кода, дать комментарий небольшой к нему, что вообще вы тут хотели написать, для чего

195:09

Speaker C

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

195:19

Speaker C

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

195:38

Speaker C

сзвёздочка и звёздочка с/ Всё, я закомментировал наш код. У нас никаких ошибок нету. Ну, помимо того, что мы теперь не используем нигде ящик инструментов FMT, и нам редактор кода на это жалуется, что типа ты взял ящик инструментов FМТ и нигде его не

195:55

Speaker C

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

196:01

Speaker C

Ну давайте заново напишем код, но уже по новой схеме. Поехали. У нас опять же должен быть изначально какой-то счёт.

196:08

Speaker C

Пускай опять же будет пять, потом, если что, его будем менять. И поехали. Первое условие. Если скор больше пятнадцати, ну, так и пишем. Если скор больше пятнадцати, тогда, если это истина, если да, тогда выводим ты, мегакрасавчик. Ну, о'кей, вводим ты

196:31

Speaker C

мегакрасавчик. Сохраняем файл. Нам сразу же автоматически возьмётся ящик инструментов FMT. И можем дальше писать код. Если скор больше пятнадцати, тогда ты мегакрасавчик.

196:41

Speaker C

Иначе у нас опять ещё одно условие. Давайте посмотрим, как это может выглядеть. Элсы, то есть иначе и опять у нас какое-то условное витвление. Что тут?

196:53

Speaker C

Если скор больше десяти, смотрим. Если скор больше десяти, если да, то ты [аплодисменты] красавчик. Если нет, то есть иначе тебе нужно ещё многому научиться.

197:12

Speaker C

[аплодисменты] Давайте запустим нашу программу, посмотрим, что она вообще работает. А, ну вот, да, у нас скор равно 5. То есть, что должно произойти, если скор больше пятнадцати? Нет, у нас пять, ну, не больше пятнадцати. Тогда отработает блок кода Элса. Теперь смотрим. Заходим в

197:29

Speaker C

эсы. У нас тут сразу же условие, если скор больше десяти, у нас скорп, 5 больше 10, нет. Поэтому выполнится опять эсы. И тут мы выведем. тебе нужно ещё многому научиться. Запускаем программу. То есть вот на вот этом вот

197:45

Speaker C

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

197:57

Speaker C

давайте протестируем быстренько для значения например 13. Сохраняем, выводим. Ты красавчик. Ну, всё правильно. Если 13, то мы в зелёной зоне. Зелёная зона, значит, ты красавчик. То есть мы и не совсем плохи, и мы не мегакрасавчики. Мы просто красавчики. Мы в зелёной зоне. Ну и

198:15

Speaker C

давайте попробуем там 20. Запускаем. Ты мегакрасавчик, да? Потому что 20 у нас в синей зоне, значит, мы мегакрасавчик.

198:21

Speaker C

Всё, программа работает. Но в чём же то самое преимущество в коде, о котором я вам говорил? Что, казалось бы, у нас такая же тройная вложенность. И по сути выглядит так кот очень похоже. У нас просто вот это вот дополнительная

198:36

Speaker C

вложенность, дополнительное ветвление, оно ушло из блока, который выполняется, если условие верно, в блок, который выполняется, если условие неверно. Но по сути код очень похож. Так в чём же то самое преимущество? А в том, что такие конструкции типа else if можно писать в

198:54

Speaker C

одну строчку. Как это выглядит? Else if score больше 10. Эссы тут вот ещё одна скобочка лишняя. Странно, что вообще за хрень произошла? А я сейчас объясню. У нас произошла оптимизация синтаксиса, так называемая. Мы избавились от тройной вложенности. Мы получили двойную

199:14

Speaker C

вложенность. И давайте проверим, что программа работает. Потом я объясню, что вообще написано. Возьмём пятёрку.

199:21

Speaker C

Запустим программу. Тебе нужно многому научиться. Возьмём 13. Те же самые запускаем. Ты красавчик. Возьмём 20.

199:30

Speaker C

Ты мегакрасавчик. То есть наша программа работает. А что же тут случилось? Мы просто использовали возможность языка, который нам предоставляет синтаксис els if. Как это читается? Просто идём сверху вниз. Если скор больше пятнадцати, смотрим. Скор у нас 20 больше пцати. Да,

199:50

Speaker C

ты мегакрасавчик. Всё, условное ветвление закончилось, потому что всё, что дальше, оно идёт только, если первое условия у нас не выполняется. То есть у нас первое условие выполняется, поэтому ты мегакрасавчик. И заканчиваем своё выполнение. Теперь смотрим, что если у

200:06

Speaker C

нас скор, допустим, будет 13. Идём к первому условию. Если скор больше 15, 13 > 15, нет, тогда это не выполняется. Мы идём дальше. Иначе, если скор больше 10, 13 > 10, да, выводится, ты красавчик.

200:25

Speaker C

Всё, это уже не выводится. И если мы ставим тут, допустим, пять, тогда если скор больше пятнадцати, 5 > 15 нет.

200:34

Speaker C

Иначе, если скор больше десяти, 5 боше 10 нет. Иначе тебе нужно ещё многому научиться. Всё это такого рода конструкция условная, условное ветвление, которое по сути является просто синтаксическим сахаром к тому, что мы написали чуть ранее, является синтаксическим сахаром вот к этой

200:53

Speaker C

конструкции, которая просто позволяет нам меньше вложенности использовать. По сути, вот это то же самое, что я вам только что показывал. Логика такая же, читается очень похоже. Если счёт больше пятнадцати, тогда ты мегакрасавчик.

201:05

Speaker C

Иначе, если счёт больше десяти, ты красавчик. иначе тебе нужно многому научиться. Но другой синтаксис, он нам позволяет избавиться от излишней вложенности, при этом сохранить в себе ту же самую логическую цепочку. То есть ход исполнения программы, он абсолютно никак не изменится. Читается это

201:23

Speaker C

абсолютно так же, но вложенности меньше. С условиями, с условными ветвлениями могут быть проблемы, потому что это не совсем очевидно, особенно когда ты только начинаешь писать код. не совсем очевидны вот такие вот оптимизации, что мы можем else if сразу писать в одну

201:39

Speaker C

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

201:56

Speaker C

числа в условия, как мы здесь меняли скор, также там меняете тоже скор или какое-нибудь другое значение, которое вы себе придумали, и смотрите, как ваша программа работает. Я, конечно же, дам домашнее задание на эту тему, но супер практика, если вы сами себе

202:11

Speaker C

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

202:31

Speaker C

условия. Допустим, если игрок набрал ровно 12 очков, то вывести Дюжина, да? То есть вот игрок сколько-то очков набрал, но если он набрал ровно 12, тогда мы должны вывести дюжина. Если игрок набрал 21 очко, тогда вывести очко. Вот. Если мы набрали 21 очко,

202:49

Speaker C

тогда выводим очко. Если игрок набрал 50 очков, то нужно написать полтинник, да? То есть тут 21, ну, тут 22, 23 и так далее до 50. Если мы набрали 50 очков, то вывести полтинник. И, соответственно, если мы не набрали никакие из этих очков

203:05

Speaker C

и не 12, и не 21 и не 50, тогда вывести ты не попал ни в какую категорию. Ну давайте опять же нарисуем схемку, как бы это могло выглядеть. Вот наша главная функция, откуда мы начинаем своё выполнение. Идём прямолинейно до первого

203:20

Speaker C

условного витуления. Давайте посмотрим, что у нас по условию. Если игрок набрал ровно 12 очков, то вывести дюжина. Ну, мы, наверное, хотим сразу же проверить, может быть, у нас дюжина, поэтому берём и смотрим.

203:32

Speaker C

Если счёт наш равен 12, тогда мы выведем дюжина, да? То есть, если ско равно 12, да получается выводим [аплодисменты] дюжина. Сразу же хочу тут оговорить один момент. В языках программирования, вообще-то, вот такая конструкция сOR = 12. Ну и в принципе, да, когда мы пишем

203:58

Speaker C

какую-то переменную равно число, эта конструкция, она уже зарезервирована под присваивание. Что я имею в виду? Давайте я опять закомментирую весь код, который мы с вами до этого писали, и покажу. То есть вот у нас, допустим, есть та же переменная скор,

204:16

Speaker C

она там у нас равна 10ти. И если мы напишем скор равно 12, вот как здесь, то что произойдёт? Мы просто присвоим переменной скоore значение 12. Давайте я выведу его на экран. Сохраняю, запускаю. 12. Да? То есть получается, мы

204:36

Speaker C

с помощью этой конструкции с вами просто присвоили переменное какое-то значение. А на самом деле мы хотели сравнить переменную со значением 12, то есть узнать скор равно ли 12. То есть мы не хотели присваивать 12, мы хотели узнать равно ли скор 12. И в языках

204:54

Speaker C

программирования для такой конструкции равно ли придумали следующий оператор. Он выглядит двойное равно. То есть не одинарное равно, которое просто присваивает переменное какое-то значение, а двойное равно, которое будет сравнивать значение переменной с значением, которое стоит справа от знака двойного равно. Давайте посмотрим, на

205:13

Speaker C

что у нас жалуется. Он говорит, что мы создали какой-то там бул и не использовали его. Ну сейчас нам не совсем понятно. Мы помним, что-то мы обсуждали про бул, но вообще непонятно, почему тут какая-то ошибка. Давайте сейчас мы к этому попозже вернёмся.

205:31

Speaker C

Сейчас пока забудем про то, что у нас какой-то бул есть. Но на самом деле он, этот самый бул, этот самый Тилин, у нас уже очень часто витает в наших с вами условных конструкциях. Просто мы пока ещё про него не знаем. Так вот,

205:44

Speaker C

возвращаемся к нашей схеме. То есть теперь мы узнали, что двойное равно - это именно сравнение значения. То есть мы проверяем, равен ли скор 12. Если бы у нас было одинарное равно, то мы бы просто в переменную скор записали 12. А

205:57

Speaker C

мы хотим именно сравнить эти значения, поэтому мы двойное равно используем. Ну, собственно, если скор у нас равен 12, тогда дюжина. Иначе, если у нас скор не равен 12ти, тогда мы хотим проверить дальше. Если скор равно 21, да, если наш

206:14

Speaker C

счёт равен 21, тогда пишем очко. Ну, опять проверяем. Если счёт равен 21, если это истина, да, тогда мы выводим с вами вот тут, да, а тут мы вводим очко, если нет, если у нас скор не 21, то есть к этому моменту мы

206:32

Speaker C

уже с вами можем узнать, что у нас скор не 12 и не 21, да, потому что мы посмотрели score 12 нет, скор 21 нет. То есть он уже и не 12, и не 21. Тогда дальше что мы смотрим? Если скоро у нас

206:47

Speaker C

50, если 50 очков, тогда выводим полтинник. Ну, давайте посмотрим. Если скоро у нас 50, тогда выводим полтинник. И если нет, если нет, тогда мы знаем, что мы и не в 12 не попали, и в 21 не попали, и в 50 мы тоже не

207:06

Speaker C

попали. То есть тогда нам нужно вывести, ты не попал ни в какую категорию. Нет, вот ты не попал ни в какую категорию.

207:13

Speaker C

Ну, давайте примерно сейчас прикинем на нашей схемке вообще значения разные и посмотрим, как она работает. Допустим, у нас счёт мы набрали там 10 с вами, функция main. И смотрим, то есть счёт у нас 10. Если 10 = 12, 10 = 12, нет.

207:29

Speaker C

Тогда смотрим. Если 10 = 21, 10 = 21, нет. Если 10 = 50, 10 = 50, нет. И у нас будет вывод: ты не попал ни в какую категорию. Ну, в принципе, оно и правильно, потому что 10 у нас вот 10 -

207:44

Speaker C

это и не 12, и не 21, и не 50 - это просто 10. Соответственно, мы не попадаем ни в какую категорию и об этом мы и выводим. Теперь давайте возьмём, например, ну, 50. Ну, то есть наш скор равен птися. И смотрим. Если 50 = 12,

207:57

Speaker C

ну, 50 = 12, нет. Если 50 = 21, нет. Если 50 = 50, да, 50 = 50. Выводим полтинник. Ну, в принципе, оно и правильно, да, по нашей схеме, как мы и хотели, что если мы попадаем в 50 из по

208:14

Speaker C

условию задачи, то нужно вывести полтинник. О'кей. Давайте теперь проверим, что будет, если у нас будет число 21. Смотрим, если скор, то есть наше число, наш счёт, который мы набрали, если счёт равен 12ти, а у нас 21. 21 = 12? Нет, 21 = 21, да, очко. То

208:34

Speaker C

есть получается, если мы набрали 21, то мы согласно условию задачи, как и нужно, как и закладывалось, выведем очко. И теперь давайте проверим, что будет, если мы возьмём 12, и мы сразу же на первом же условном ветвлении попадём в да, потому что у нас

208:48

Speaker C

12. И смотрим, если 12 = 12, да, дюжина. Ну, выглядит пока всё валидно. Осталось только реализовать эту схемку в коде и посмотреть, как это вообще будет выглядеть на языке программирования. Ну, давайте начнём писать. То есть, в принципе, переменная скоро у нас уже

209:02

Speaker C

создана. Я удалю её вывод. И давайте просто по схеме идём. И сразу же первое условное ветвление. Если скоore равно 12, вот как это выглядит на языке программирования, не присваивание, с помощью которого мы просто можем поменять значение переменных, да, и вскоро записать три,

209:19

Speaker C

ну или любое другое число. Тут именно сравнение с двенадцатью, что мы проверяем, что скор равен ли 12. То есть, если у нас скор равен 12, тогда мы сразу же должны вывести дюжина.

209:34

Speaker C

Дальше нет. То есть нет - это иначе как бы, да, Элса. То есть если мы не 12, иначе что? Опять условное ветвление.

209:42

Speaker C

Если скор равно 21, ну давайте тут напишем. Если скор равно 21, тогда выводим очко. Если скор 21, тогда очко. Нет. То есть иначе мы иначе то есть, ну вот опять же пойдём сверху вниз. Если скор равно двенадцати, тогда выводим дюжина. Иначе вот наш блок

210:08

Speaker C

иначе вот он весь. То есть вот это вот иначе, которое тут - это по сути вот всё, что вот здесь вот должно у нас быть, да? Потому что мы проверили, что скор равно 12. Нет, и мы попали вот в

210:19

Speaker C

этот весь блок. То есть вот он весь этот наш блок, который нет, но мы его ещё не дописали. Тут смотрим. Если скор равно 21, тогда очко. Ну вот, если скор равно 21, вводим очко. Иначе, то есть вот это

210:31

Speaker C

иначе, которое я вот выделил слева, это уже вот этот вот блок оставшийся. И тут мы должны проверить, если счёт равен пятидесяти, если счёт равен пятися, да, ну, то есть если счёт всё-таки равен пятидесяти, тогда мы вводим полтинник, иначе ты не попал ни в какую

210:49

Speaker C

категорию. То есть вот это наше самое иначе, самое последнее, вот оно. Ты не попал ни в какую категорию. Давайте проверим вообще нашу программу, как она работает. Ну давайте попробуем вот с числом 10, например. Что у нас будет с числом 10? Ты не попал ни в

211:06

Speaker C

какую категорию. Ну оно и логично, потому что 10 у нас это и не 12, и не 21, и не 50. То есть и не дюжина, и не очко, и не полтинник. Просто 10. Ну ты не попал ни в какую категорию. О'кей.

211:17

Speaker C

Давайте теперь напишем здесь 50. То есть у нас был счёт 50. Запускаем полтинник. То есть он правильно узнал то, что наше 50 - это полтинник. Как это сработало?

211:27

Speaker C

Вот у нас было 50. Мы проверяем, счёт равен 12? Нет, отрабатывает этот блок. Потому что если бы счёт был равен 12ти, сразу же отработал бы этот блок и всё. А так у нас счёт равен 12. Нет, отрабатывает блок Элса. В блоке Элса мы

211:44

Speaker C

смотрим, если счёт равен 21, а у нас 50. 50 = 21. Нет. опять отрабатывает блокса.

211:50

Speaker C

Тут мы смотрим, если счёт равен пти, а у нас счёт 50, 50 = 50, да, наконец-таки отрабатывает не блок эсы, а отрабатывает основной блок полтинник. И наше условное ветвление заканчивается. Ну, собственно, как и на схеме. Теперь давайте проверим

212:06

Speaker C

21. Запускаем очко. Ну, тут то же самое. То есть 21. Мы проверили счёт равен 12. То есть 21 = 12. Нет, 21 = 21, да? Всё, отработает этот блок и Элса всё уже не отрабатывает. Ну, собственно, давайте проверим теперь для двенадцати.

212:25

Speaker C

Запускаем Дюжина. Почему? Потому что мы сразу же с первой проверки попали в основной блок и всё, блок иначе уже не выполнялся. Типа, если счёт равен 12, у нас счёт 12. Итак, 12 = 12, да? Всё, мы попали вот сюда. Всё, вот это L у нас

212:42

Speaker C

уже не отрабатывает. Но, как мы можем видеть, довольно простая программка-то, на самом деле. То есть, что она умеет?

212:48

Speaker C

Она умеет проверять, в какую категорию мы попали. Полтинник очко дюжина или никакая. Но у нас уже появилась вложенность. 1 2 3 4 Четверная вложенность. Это уже довольно большая проблема. Вот в настоящем коде, да и даже в этом примере. Четверная

213:05

Speaker C

вложенность - это проблема. Уже тяжело читать вот этот вот кусок кода, потому что слишком много нагромождения, слишком большая вложенность. Но тут можно использовать то, о чём я вам показывал в предыдущем примере, эту конструкцию LCF.

213:19

Speaker C

Она тут как раз-таки очень хорошо подходит. То есть мы можем вот этот вот блок if не делать дополнительную вложенность, а использовать вот это вот if. Как это выглядит? LC if тут скобочка лишняя.

213:33

Speaker C

Сохраняем. Когда мы сохраняем, у нас сразу же код автоматически будет форматироваться. И тут у нас видим опять else if. Это тоже можно объединить. Оп.

213:43

Speaker C

И опять скобочку убираем, потому что у нас тут лишняя скобочка. Сохраняем. Файл форматируется. И как мы видим, мы программу, которая только что была с четверной вложенностью, превратили в программу, у которой двойная вложенность. А это как бы в два раза

213:56

Speaker C

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

214:08

Speaker C

четверная вложенность - это прямо как нагромождение выглядит. А когда у нас двойная вложенность, то выглядит как просто аккуратненький такой проход по разным нашим числам и проверка, попали ли мы в какое-то число или нет. Наш код своей логической цепочки не изменяет. Он

214:24

Speaker C

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

214:34

Speaker C

Если вы сначала будете писать просто ровно как на схеме, то есть если, да, иначе, и у вас будут рождаться такие вложенности, это неплохо. Это даже хорошо, потому что вы, опять же, будете практиковаться, потом уже с опытом вы начнёте видеть, что если у вас вот такой

214:50

Speaker C

вот if, if, то эти else if можно объединить и сохранить себе целый уровень вложенности. Вот опять elsec if можно объединить, удалить скобочку и сохранить себе целый уровень вложенности. Давайте пройдёмся по коду.

215:05

Speaker C

Вот тут у нас число в счёте, допустим, будет пять. И смотрим, как это вообще читается. Если 5 = 12, 5 = 12, нет.

215:14

Speaker C

Иначе, если 5 = 21? Ну, нет. Иначе, если 5 = 50, нет. У нас как бы, ну, пять лежит в счёте, 5 не равно 50. Иначе ты не попал ни в какую категорию. Ну, оно как бы и верно, что у нас если пять, то

215:28

Speaker C

мы не попали ни в какую категорию. Теперь давайте тут поставим, например, 50. То есть, если 50 равно 12, нет.

215:36

Speaker C

Иначе, если 50 = 21, нет. Иначе, если 50 равно 50, да? Да. И всё. Если наш счёт равен 50, мы выводим полтинник. Ну и тут давайте поставим там 21. Смотрим, если счёт равен 12, ну, то есть 21, 21 = 12.

215:53

Speaker C

Нет. Иначе, если счёт равен 21, а у нас счёт 21, 21 = 21. Да. Всё, мы попадаем сюда, выводим очко, и наша программа завершается у выполнение, потому что это читается, повторюсь, если счёт равен 12, тогда выводи дюжина. Иначе, если счёт

216:10

Speaker C

равен 21, тогда выводи очко. Иначе, если счёт равен пятидесяти, тогда выводи полтинник. Иначе вот это вот. То есть это просто обычное условно ветвление. И мы сейчас разобрали несколько примеров, как оно может использоваться. О чём же я говорил, когда вспоминал булин? То есть,

216:28

Speaker C

да, когда мы просто с вами писали скор равно 13, к примеру, любое другое число 16, когда у нас двойное равно, нам редактор кода говорит, что тут какой-то тип бул и непонятно о чём речь. На самом деле, если более в общем плане разобрать

216:45

Speaker C

эти самые условные конструкции, они работают с типом bull. То есть, помните, я вам говорил, что тип буll - это либо true, либо false, либо да, либо нет. Я либо подписан на какой-то YouTube канал, либо не подписан. Давайте я сейчас

216:59

Speaker C

закомментирую вот этот код. Давайте представим, что перед нами стоит. Следующая задача. Нам дана информация, что человек либо подписан на YouTube канал, либо не подписан. Нам вот говорят конкретно, в каком состоянии находится человек. Либо подписан, либо нет. И у

217:14

Speaker C

нас задание, что если человек всё-таки подписан на YouTube канал, то нужно сказать: "Ты подписан на мой YouTube канал спасибо".

217:22

Speaker C

Иначе, если человек не подписан, нужно сказать ему: "Пожалуйста, подпишись на мой YouTube канал". И давайте посмотрим, как это могло бы выглядеть на схеме. То есть опять же, вот у нас есть наша главная функция, из которой начинается выполнение линейное. И потом мы

217:34

Speaker C

встречаемся с первой условной конструкцией. И тут мы хотим проверить, если подписан, тогда если да, то получается нам нужно вывести: "Ты подписан на мой YouTube канал? Спасибо". Иначе, если нет, тогда нужно вывести вот, пожалуйста, подпишись на мой YouTube канал. Так вот, как бы мы

217:55

Speaker C

могли это сделать с помощью кода? То есть тут у нас как бы информация о том, что подписан, она может принимать только два значения, либо да, либо нет. Это не какое-то число, как мы с вами разбирали в предыдущих примерах. Это именно

218:08

Speaker C

информация логическая, которая может быть представлена либо положительным значением, либо отрицательным. То есть третьего не дано. Это тот самый тип бун.

218:18

Speaker C

Мы с вами проходили переменные типа бун. Давайте напомню, как это выглядит. Вот я создам переменную subscribed. Subscribed с английского переводится как подписан. Ну, то есть подписан ли. И придам ей значение true.

218:33

Speaker C

Что это значит? Помните, я говорил, что true - это значит да. Просто это так странно выглядит, чтобы оптимизировать нам занимаемую память. Чтобы мы не занимали слишком много памяти. Создан специальный тип бул, который может принимать либо true, что значит да. либо

218:47

Speaker C

false, что значит нет. Ну и, соответственно, давайте я изначально сделаю её true. И просто будут следовать нашей схеме, чтобы реализовать вот эту вот задачу. То есть схема говорит, что нам нужна условная конструкция, которая проверяет, подписан ли. Ну давайте

219:02

Speaker C

посмотрим. Если подписан, тогда выводим. Ты подписан на мой YouTube канал. Спасибо. Иначе, если нет, тогда, пожалуйста, подпишись на мой YouTube канал. Давайте сохраним файл, запустим программу, посмотрим, что у нас выйдет.

219:22

Speaker C

Ты подписан на мой YouTube канал? Спасибо. Ага. А почему она попала именно сюда? Почему мы не попали в этот блок? А давайте тут поставим false. Сохраняем, запускаем. Пожалуйста, подпишись на мой YouTube канал. А всё потому, что переменная subscribed, она

219:41

Speaker C

имеет тип данных bullan, ну, тот самый, то есть либо true, либо false. И мы в условной конструкции всегда работаем с типом данных булин. Даже когда мы с вами проверяем какое-то значение на равенство, то вот это под капотом преобразуется тоже в тип данных булин.

220:01

Speaker C

Сейчас объясню поподробнее. Ну вот наша subsced. Я думаю, вы уже поняли, что subscribedтed может представлять информацию о том, что человек либо подписан на YouTube канал, либо нет. И соответственно, да, это значит true. То есть мы выведим, ты подписан на мой

220:16

Speaker C

YouTube канал. Иначе мы выведем, пожалуйста, подпишись на мой YouTube канал. А теперь давайте я этот код закомментирую и раскомментирую код из нашего предыдущего примера. Сохраняю файл. Сразу же применяется форматирование, которое удаляет лишний отступ. И давайте посмотрим, что же тут

220:32

Speaker C

на самом деле происходит. Вот у нас есть информация, да, подписан либо да, либо нет. Это булевская переменная. Теперь возвращаемся к нашей предыдущей схеме.

220:41

Speaker C

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

221:05

Speaker C

ли счёт двенадцати? Либо да, либо нет. И поэтому мы можем это использовать в условной конструкции. Либо да, либо нет.

221:14

Speaker C

То же самое, иначе, если и тут тоже булевская переменная, просто мы сравниваем с другим числом. То есть равен ли счёт 21, либо да, либо нет. На самом деле мы даже значение вот этих вот логических операций можем присваивать в

221:30

Speaker C

переменные. Давайте я посмотрю, что это значит. Опять закомментирую вот этот вот код и создам вот тут вот новую числовую переменную number. Просто её назову.

221:37

Speaker C

Пускай она у нас будет один. И смотрите, я хочу узнать, равно либер у нас пяти.

221:45

Speaker C

Давайте я назову переменную равно 5 и ей присвою значение, которое у нас является результатом логического выражения.

221:54

Speaker C

Логическое выражение number равно пти. Ну, тут, конечно же, так как мы создаём новую переменную, то нужно двоеточие добавить, да, потому что равно пяти у нас новая переменная. И значит, двоеточие нужно написать, что значит, что мы будем создавать новую переменную.

222:09

Speaker C

number равно п. Это выражение, которое я выделил, оно является логическим. Логическое выражение может у нас иметь значение либо true, либо false. То есть либо правда, либо ложь. Number у нас может быть либо равно пяти, либо нет.

222:26

Speaker C

Давайте выведем на экран значение переменной равно [аплодисменты] пть. Сохраняю, запускаю. False. Что это значит?

222:38

Speaker C

Намр равно пяти? Нет. Ну, потому что numberр у нас один, как бы 1 равно пти.

222:43

Speaker C

Нет. И вот это нет мы записали в переменную равно и вывели на экран. Соответственно, тут бы мы что с вами не присваивали? Допустим, number 3.

222:53

Speaker C

Запускаем. Опять флse. Почему? Потому что 3. И мы смотрим 3 равно 5. Нет. То есть опять это нет, опять false. А если пять поставим, запускаем true, то есть да, numberр у нас 5, 5 = 5, да, и поэтому выводится, да. В наших

223:13

Speaker C

предыдущих примерах, на самом деле, вот тут вот под капотом тоже происходило вычисление логических значений и проверка их на истинность. То есть мы брали с вами счёт и смотрели, счёт равен 12. И у нас получались те же самые значения, либо true, либо fфse. То есть

223:32

Speaker C

счёт равен 12, а он у нас 21. Изначально 21 = 12, нет, то есть фse. И если fse, тогда отрабатывает блокса. И тут мы опять смотрим, если счёт равен 21, 21 = 21, да? То есть true. Если true, то

223:50

Speaker C

отрабатывает этот блок, и блок Элса уже не отрабатывает. Ну и, соответственно, тут во всех примерах происходило всё то же самое. Даже когда мы с вами сравнивали на больше, меньше, это тоже было логическое выражение, потому что скор больше десяти. Может быть либо да,

224:07

Speaker C

либо нет. Скор либо больше десяти, либо нет. Вот берём скор 5. И мы смотрим скор больше 10, то есть 5 боше 10.

224:18

Speaker C

Нет, значит, отрабатывает блокса. Тебе нужно ещё многому научиться. Ну и так дальше. Допустим, у нас счёт был бы 13, то есть 13. 13. Труue, да? То есть истина. Тогда выполняется вот этот блок кода, который самый первый идёт, потому

224:34

Speaker C

что он, ну, типа, что-то, какое-то условие. Если оно истино, то выполняется блок кода, который сразу же идёт за этим ифом. И тут дальше смотрится 13 > 15 фse. Ну, то есть 13 не больше 15, это ложь. То есть нет. Ну, значит,

224:49

Speaker C

выполняется вот этот код, который под блоком Элсы. Чтобы ещё немножко закрепить логические выражения, давайте создадим несколько переменных. Вот у нас уже есть равно пять. Давайте создадим переменную больше 12. И она у нас будет сохранять в себе результат логического

225:07

Speaker C

выражения numberр больше двенадцати. И давайте её тоже выведем на [аплодисменты] экран. Сохраняем, запускаем и смотрим. У нас первое true, второе false. Почему number 5? Первое мы смотрим, равен ли number пяти. То есть 5 = 5, да, true.

225:29

Speaker C

Вот выводится true. Ну и, соответственно, больше двенадцати. Мы смотрим number больше двенадцати. У нас 5 больше двенадцати. Нет, ну то есть 5 меньше две. И, соответственно, выводится фse, потому что больше 12 - это фse, это ложь. То есть набор не больше

225:43

Speaker C

двенадцати. Давайте теперь поставим здесь число 15, сохраним и выведем на экран. А теперь у нас сначала false, потом true. Я думаю, кто-то уже мог догадаться, почему у нас число 15. И мы смотрим 15 = 5. Ну нет, типа 15 не равно

225:59

Speaker C

пяти, значит равно 5. У нас fфse. Вот он вводится false. Потом больше 12. Смотрим. 15 > 12. Ну да, 15. Ну значит, правда, истина. Вот оно и выводится. И результаты этих выражений мы точно также можем использовать в условных

226:14

Speaker C

конструкциях. Давайте я покажу. То есть равно 5. Давайте посмотрим. Если у нас равно пяти, тогда я хочу вывести number равно пти. Если у нас больше 12, тогда я хочу вывести больше 12. Что сейчас вообще произошло? Наверное, для вас вот эти вот

226:36

Speaker C

огрызки выглядят довольно странно, потому что мы привыкли видеть условные конструкции с блоком, который отвечает за да и с блоком, который отвечает за нет. То есть if, который отвечает за да и который отвечает за нет, то есть за true и за false. Но язык

226:55

Speaker C

программирования нам позволяет писать вот такие вот огрызки, пренебрегая блоком эсы. Для чего это нужно? Да, когда мы просто по ходу выполнения программы хотим узнать какое-то условие.

227:06

Speaker C

Если оно истино, то что-нибудь вывести на экран или что-нибудь сделать. Но если условие ложно, то ничего не делать. Ну как вот в текущей нашей задаче, что мы просто хотим вывести равно пяти, если равно пяти и больше 12, если больше

227:21

Speaker C

двенадцати. Но иначе нам делать ничего не надо. То есть равно пяти иначе, да, ничего мы не хотим делать. Ну, просто если равно пяти, то вывести равно пяти.

227:31

Speaker C

Ну, то есть мы как бы могли бы тут написать этот блок, могли бы его даже оставить, но он нам не нужен. Как понять, когда этот блок нужен, когда не нужен? Это просто практика, это опыт. Вы начнёте переключать своё мышление на

227:44

Speaker C

мышление программиста. Вы начнёте представлять уже все эти логические выражения, вы начнёте их чувствовать и начнёте сразу понимать, как лучше поступить, как лучше условия написать, нужен ли вам блок Элса, не нужен ли вам блок Элса, нужен ли вам блокса if,

228:00

Speaker C

сколько вам этих ифов нужно, нужно ли после этого эса или не нужно. Может быть, вам вообще это ничего не нужно и нужно один if написать. Это всё с опытом. Вы просто рисуете себе вот такие вот схемки и потом пытаетесь это

228:15

Speaker C

всё написать на языке программирования проверяете обязательно написанную вами программу разными входными значениями, а потом что-то уже делаете с той информацией, которую получили.

228:27

Speaker C

Понимаете, вы либо правильно решили программу, либо неправильно. И таким образом по чуть-чуть, по чуть-чуть практика практика практика будете набивать себе руку. По сути, мы с вами разобрали условные конструкции. Мы узнали, что есть логические выражения, которые стоят в основе условных

228:43

Speaker C

конструкций. Мы узнали, что эти логические выражения могут принимать либо true, либо fфse. Узнали, что если логическое выражение в условном блоке принимает trueue, тогда выполняется первый блок. Если условное выражение принимает fф, тогда выполняется блокса.

228:59

Speaker C

А сколько уже в этом блоке Элса будет других блоков? Какой там будет код написан, это значения не имеет, потому что мы рассматриваем каждый блок кода отдельно. Ну вот опять же, то есть тут вот у нас скоore больше десяти. Если это

229:13

Speaker C

true, тогда выполнится этот блок кода. Если фс- это блок кода. А если мы хотим узнать, что конкретно выведется из этих двух выводов, нам нужно отдельно рассмотреть вот эту условную конструкцию. И мы тут смотрим. Скор больше пятнадцати. Если да, тогда ты

229:28

Speaker C

мегакрасавчик. Если нет, тогда ты просто красавчик. Повторюсь, с первого раза условные конструкции могут не зайти.

229:36

Speaker C

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

229:57

Speaker C

в него значениях и в зависимости от них уже даёт разные результаты. Потому что программа - это не просто сверху вниз пройтись, как бы, да, и всё сделать линейно. Программа - это практически всегда какое-то ветвление. Как вариант, это может быть условное ветвление. И

230:15

Speaker C

дальше мы с вами рассмотрим ещё другие типы витвлений, которые есть в программе, которые позволяют выполнять код не просто сверху вниз, а по-разному.

230:24

Speaker C

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

230:42

Speaker C

Всё, что нам осталось - это разобрать несколько более сложные условные выражения. Что я имею в виду? До этого мы пользовались лишь односложными условными выражениями. То есть у нас было, например, if счёт больше пяти. И тогда мы что-то там делали, тоже что-то

230:58

Speaker C

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

231:15

Speaker C

присвоить е значение либо true, либо false. И на основе значений этой переменной мы также делали какое-то логическое витвление. То есть, если там один, тогда что-то там, и что-то там. Но сейчас я покажу несколько более сложные условные выражения. То есть не

231:33

Speaker C

односложные, как у нас сейчас, а многосложные, когда они будут состоять сразу же из нескольких условий в одной условной конструкции. Допустим, у нашей игры Flppy Bird появилось большое комьюнити, и в этом комьюнити появились какие-то локальные мемы. И один из этих

231:50

Speaker C

локальных мемов говорит, что если игрок набрал меньше шести и больше шестнадцати очков, то он попал в петушиную зону. Ну, почему-то комьюнити вот такой вот мем сгенерировала. И перед нами, как перед разработчиками этой игры Flppy Bird, стоит задача, что необходимо этот мем

232:06

Speaker C

поддержать. В чём задача? Если игрок набрал меньше шести или больше шестнадцати очков, то вывести ему: "Ты попал в петушиную зону". Давайте подумаем, как бы мы могли это делать. То есть нам нужно какое-то условие, которое бы нам помогало понять, что попал игрок

232:24

Speaker C

либо сюда, либо сюда, то есть нам уже нужно сложные условия, потому что односложным условием мы тут не отделаемся. Ну, что бы мы могли сделать?

232:34

Speaker C

Проверить, если счёт меньше шести. Ну, допустим, мы бы написали, если наш счёт меньше шести, тогда мы бы открыли скобочки. В этих скобочках бы вывели игроку, что ты попал в петушиную зону.

232:48

Speaker C

О'кей. Но это условие, счёт меньше шести, оно бы не покрывало вот эту зону. Типа, а что, если игрок попадёт в эту зону? Ну ладно, давайте тогда, если счёт больше шестнадцати. Хорошо, мы покрыли эту зону. А эту зону как покрыть тогда? То

233:05

Speaker C

есть у нас либо был бы вариант, что нам нужно последовательно вот так вот писать два условия, и в первом мы бы выводили на экран, ты попал в петушиную зону.

233:17

Speaker C

И во втором бы мы точно также выводили это же самое на экран. Но мы бы столкнулись с таким явлением, как дублирование кода. Потому что если бы в задаче было не только вывести на экран ты попал в петушиную зону, а какая-то более сложная логика,

233:33

Speaker C

то это какая-то более сложная логика, она бы дублировалась. А в принципе в программировании такое явление, как дублирование кода - это так же плохо, как и большая вложенность. То есть это усложняет код, это усложняет написание нового кода, это делает систему слишком

233:48

Speaker C

сложно. Из-за чего? Потом и работать над таким кодом неприятно. И в принципе он потом будет работать не так, как ты хочешь, потому что система слишком сложная, ты не можешь всё предусмотреть, у тебя куча копирований кода одних и тех

234:00

Speaker C

же. Поэтому мы бы хотели, вообще-то, всё, что у нас происходит в этой задаче, под одно условие как-то поместить, чтобы у нас не было дублирования кода. И у нас есть средство языка, которое позволяет это делать. Мы можем написать буквально

234:14

Speaker C

то, что нам нужно. Нам нужно вывести: "Ты попал в петушиную зону". Если игрок набрал меньше шести или больше шестнадцати очков. В программировании у нас есть это самое или выглядит оно следующим образом. Это две вертикальные палочки. И тут мы можем написать score

234:32

Speaker C

больше 16. Что тут произошло? Мы поставили условие. Если счёт меньше шести или больше стти, тогда выполни вот эту логику. Ну, соответственно, выведи на экран. Ты попал в петушиную зону. Как это будет работать? Если у нас будет какое-то число, например, вот в этой

234:51

Speaker C

зоне, например, двоечка. Мы посмотрим счёт меньше шести, то есть 2 меньше. Верно? И всё. И нам одного этого выполненного условия бы хватило, чтобы всё выражение стало истинным. И тогда бы мы вывели на экран. ты попал в петушиную зону. Или возьмём, например, 19. Тут бы

235:09

Speaker C

мы пошли. Если 19 меньше 6ше, ну 19 меньше 6шести, нет, это было бы ложное, но зато 19 >. Да, вот это выражение нам бы дало true, то есть истина. И благодаря ему одному мы бы тоже попали в эту зону. То есть это оператор или

235:27

Speaker C

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

235:44

Speaker C

истина, и мы выполним этот блок кода. И наоборот, если у нас это выражение истина, то уже неважно, тут истина или ложь. В любом случае, у нас всё выражение даст истину, потому что у нас оператор или то есть или нам подходит

235:57

Speaker C

хотя бы одно из них. Если хотя бы одно из них истина или это, или это, тогда мы можем говорить, что всё выражение истина, и переходить к этому блоку. Но выражение, содержащее или, будет ложным только, если оба под выражения ложны.

236:15

Speaker C

Допустим, у нас число 10, и мы смотрим счёт меньше, то есть 10 меньше 6.

236:22

Speaker C

10 нет, 10 боше, это ложно. 10 больше 16. Нет, 10 меньше 16, это тоже ложное.

236:31

Speaker C

Соответственно, у нас и тут ложь, и тут ложь. И тогда только, когда везде ложь слева и справа, тогда оператор или делает всё выражение ложным, и мы уже ничего не будем выводить. Как раз то, что нам нужно, что если у нас либо

236:47

Speaker C

меньше шести, либо больше шестнадцати, тогда выведи, ты попал в петушиную зону. Иначе, если мы попали в эту зону, да, тогда ничего не выводи.

236:59

Speaker C

Это значит, что нам тут очень хорошо подходит условие или и - это как раз-таки то самое усложнение условных выражений, о котором я говорил. То есть мы уже не просто смотрим, что, например, счёт меньше шести, а мы это условное

237:13

Speaker C

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

237:29

Speaker C

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

237:42

Speaker C

Да, просто так и пишем. Если у нас счёт меньше или счёт больше ст, тогда мы выводим это самое сообщение на экран.

237:52

Speaker C

Всё, сохраняем файл и запускаем [аплодисменты] программу. Ничего не вывелось. Почему? Ну, потому что у нас счёт 10. 10 у нас в обычной зоне. Мы не попали в петушиную зону, и у нас ничего не вывелось, потому что это условие не выполнилось. Для

238:09

Speaker C

наглядности можно тут добавить Элса и вывести Ты не попал в зону. Запускаем программу. Ну и видим, что у нас отработал блок Элса, который мы можем, в принципе, не писать, если нам этого не требуется, но если мы хотим или если того требует задача, то мы

238:28

Speaker C

пишем блок эсы, который отрабатывает, если условия ложные. То есть, что у нас тут произошло? Давайте я вот посредством комментария напишу. Вот это скор меньше у нас стало равно fse.

238:41

Speaker C

Почему? Потому что 10 меньше. Нет, 10 больше. Скоore меньше fльс. Дальше у нас было скор больше 16. Скор больше 16 тоже фолsче меньше 16, да? Получается это ложное выражение, что скор больше стнати - это неправда, это ложь. И у нас

239:01

Speaker C

получилось, что false и false. Или даёт фс в том случае, если оба выражения ложны. То есть мы и сюда не попали, и сюда не попали. А для оператора или чтобы всё выражение вернуло true, нужно, чтобы хотя бы одно из подвыражений

239:18

Speaker C

вернуло true. Ну, собственно, вот так это и выглядит в коде. Давайте поставим, например, пятёрочку. Пятёрочка у нас уже вполне в петушиной зоне. Запускаем программу. Всё, ты попал в петушиную зону, да, потому что пятёрочка. Ну, можем троечку, в принципе, то же самое

239:31

Speaker C

будет. И теперь проверим что-нибудь из правого промежутка. Ну вот двадцаточку возьмём. 20. Запускаем. Опять ты попал в петушиную зону. Но если мы возьмём 16, запускаем, ты не попал в зону. Ну, соответственно, мы никуда не попали, потому что 16, опять же, оба выражения

239:51

Speaker C

далофс, потому что 16 и не меньше шести, и не больше. 16 равношестнадцати, но не больше. Поэтому тут фолс, тут фS и в итоге всё дало флс и отработал блокса.

240:03

Speaker C

Вот я задачку и примерчик, который относится к оператору или вынес в отдельную секцию. Сейчас мы её не рассматриваем. Мы рассматриваем новую задачу. У нас следующая задача стоит.

240:12

Speaker C

Если игрок набрал больше восьми и меньше пнадцати очков, то вывести ему: "Ты попал в яблочко". То есть у нас условие, что игрок должен конкретно попасть в эту зелёную зону, да, попасть в яблочко. То есть он должен набрать больше восьми, но

240:30

Speaker C

при этом меньше пятнадцати. Мы должны прямо вот в эту зону с вами попасть. Опять же, как бы мы это могли сделать при помощи тех навыков, которые у нас уже есть. Ну, мы бы могли написать что-то типа если счёт больше восьми, то

240:47

Speaker C

есть мы бы сразу попали вот в эту зону. И потом тут ещё дополнительным ифом посмотреть, если счёт меньше [аплодисменты] пти. Ну и тут мы бы уже точно с вами знали, что мы как раз-таки попали в яблочко.

241:05

Speaker C

Но в чём тут опять у нас минус? В том, что мы снова начинаем увеличивать нашу вложенность. У нас тут уже двойная вложенность появилась на ровном месте.

241:14

Speaker C

Как бы этот код, он нашу задачу-то выполняет. То есть он смотрит сначала, если счёт больше восьми, а потом, если счёт действительно больше восьми, он смотрит: "А если счёт ещё и меньше пятнадцати, оп, и всё, и мы попали в

241:28

Speaker C

яблочко". И выведится: "Ты попал в яблочко". Но повторюсь, тут у нас дополнительная вложенность, и у языка программирования есть возможность не писать вот так вот ифы друг в друга несколько раз, если нам нужно какое-то сложное условие, там, да, скоore там ещё

241:43

Speaker C

равно там 12 и и что-нибудь такое. Мы можем это всё заменить оператором. И то есть у нас в условии нужно, чтобы счёт был больше восьми и меньше пятнадцати.

241:56

Speaker C

Это всё можно написать буквально одним, но сложным условием. Точно так же пишем. Если счёт больше восьми и счёт меньше 15, тогда выводим на экран ты попал в яблочко. Что тут случилось? До этого мы использовали оператор или это две такие палочки.

242:17

Speaker C

Сейчас у нас оператор и - это два амперсанда. То есть это оператор и он точно так же, как оператор или берёт выражение слева, берёт выражение справа.

242:29

Speaker C

и производит над ними логическую операцию, но делает это по другим правилам. Если до этого в случае с оператором или нам было достаточно, чтобы хотя бы одно из подусловий было истинным, и тогда сразу же всё выражение становилось истинным, то в случае с

242:46

Speaker C

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

243:05

Speaker C

всё выражение истинным. И только тогда мы выведем: "Ты попал в яблочко", если выполняется и это подусловие, и это подусловие. В этом и отличие этих операторов. Они нам помогают строить более сложные выражения. Они нам помогают писать более красивый код,

243:21

Speaker C

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

243:39

Speaker C

блок кода. Или нам нужно, чтобы оба условия сразу были истинными. И только тогда мы будем выполнять блок коды. Это всё нужно продумывать перед тем, как начинаете писать код. Можно написать схемку, можно нарисовать какой-нибудь рисунок, но главное - это понимать, что

243:55

Speaker C

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

244:07

Speaker C

у нас необходимость, чтобы мы попали в яблочко. Ну, поэтому давайте я напишу, если счёт больше восьми и счёт меньше 15, тогда выводим: "Ты попал в яблочко".

244:20

Speaker C

Ну и, соответственно, иначе можно написать что типа ты не попал в яблочко. Сохраняем. Ну и давайте запустим. Нам пишут, что мы не попали в зону и не попали в яблочко. Почему у нас скор 16? И как мы видим на рисунке, 16 у

244:39

Speaker C

нас и не в петушиной зоне, и не в яблочке. Ну, просто 16. Давайте возьмём теперь 12 число. Запускаем программу. Ты не попал в зону, ну, потому что 12 - это не петушиная зона, но ты попал в яблочко.

244:54

Speaker C

Как раз-таки мы попали в яблочко. Ну и давайте возьмём что-нибудь из петушиной зоны. Так, чисто для наглядности там 21.

245:00

Speaker C

Запускаем. И вот ты попал в петушиную зону. Верно. И ты не попал в яблочко.

245:06

Speaker C

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

245:13

Speaker C

У нас два условия: скор больше восьми и скор меньше пнадцати. Значит, скор больше восьми. Вот у нас 21. Смотрим.

245:21

Speaker C

Скор больше восьми. Да, правда, потому что 21 Вот скор 21. 21 > 8. Верно? Ну вот, а вот 21. То есть 21 гораздо больше восьми. То есть это true. Скор меньше 15, это фSE. Почему? Потому что 21 < 15.

245:42

Speaker C

Нет, 21 > 15, а 21 < 15 - это ложное выражение, потому что 21 > 15. И, соответственно, наш оператор И нам выдаст ложь, потому что одно из его подвыражений ложное. Чтобы оператор и выдал в целом true, нужно, чтобы оба под

246:03

Speaker C

выражения были true. Если хотя бы одно из них фalse, как мы видим, вот это вот, то всё выражение оборачивается fфse.

246:11

Speaker C

Хотя, казалось бы, у нас здесь true, но так как мы потребовали, что всё выражение должно быть истиним только если и это истина, и эта истина, но так как у нас тут ложь, то требование не выполняется и выводится: "Ты не попал в

246:27

Speaker C

яблочко". Вот примерно такая логика работы этих усложнённых выражений. У нас есть оператор или и оператор и, благодаря которым мы можем писать более лаконичный код, но которые, повторюсь, накладывают на нас, как на программистов, больше ответственности.

246:42

Speaker C

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

247:00

Speaker C

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

247:19

Speaker C

значения, которые меньше 15. Вот. значение, которые меньше 15. И так как у нас оператор или, то нам подойдёт число, которое лежит тут, или которое лежит тут. То есть нам не важно, чтобы это число было конкретно на пересечении, потому что у нас или то есть нам

247:37

Speaker C

подойдут и все числа, которые больше восьми, и все числа, которые меньше пятнадцати. То есть нам подойдут абсолютно любые числа вообще на всём числовом промежутке. Отрицательные, положительные от плюс бесконечности до минус бесконечности. Всё, потому что мы просто с вами перепутали условия, вместо

247:54

Speaker C

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

248:10

Speaker C

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

248:28

Speaker C

тут бул один или бул 2. Давайте рассмотрим сначала его. То есть логическое или, то есть у нас сначала одна переменная, вторая переменная, между ними или и что же будет в итоге?

248:40

Speaker C

Ну, смотрим. true или true будет true, потому что или у нас true даёт, если хотя бы одно из них true. True false true. Потому что у нас есть хотя бы одно true, в итоге будет true. False или true, тоже true, потому что неважно, на

248:57

Speaker C

первом месте true, на втором месте true или два true. В итоге будет true, потому что оператор или нам достаточно, что хотя бы одно условие у нас выполняется.

249:07

Speaker C

Второе, если выполняется, ну, хорошо, но нам достаточно, что только одно выполняется. Ну, и фS или фолs то есть, когда у нас и то не выполнилось, и это не выполнилось, вот тогда у нас будет ложь. Вот это логическое или теперь

249:22

Speaker C

рассмотрим логическое и, то есть у нас бул о, бул 2, между ними и, ну, и что же будет в итоге? То есть true и true.

249:31

Speaker C

True, потому что и оператор даёт в итоге true только если оба под выражение у нас true. Ну и, соответственно, true и false даёт false, потому что если хотя бы один fse, тогда у нас в итоге будет false.

249:46

Speaker C

Тут тоже у нас false и true. Ну, значит, false, потому что неважно, у нас fse будет на первом месте стоять или на втором. В итоге оператор I нам даст false, потому что для того, чтобы оператор I дал true, нужно, чтобы и

250:00

Speaker C

левое, и правое под выражение были true. Ну и, соответственно, false. И false у нас тоже даёт false, потому что и это ложно, и это ложно. Ну, в итоге даже зацепиться не за что, так сказать, вот будет ложно. Это таблица логических

250:12

Speaker C

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

250:27

Speaker C

Рассмотрим эту табличку на небольшом примерчике. То есть, допустим, у нас есть две булевские переменные. Одна переменная хранит в себе информацию о том, солнечный ли сегодня день. Я назову её сани и пускай будет true. А вторая будет хранить себе информацию о том,

250:41

Speaker C

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

251:08

Speaker C

гулять, если будет солнечная погода. Ну и смотрим. Если солнечная погода и выходной, тогда я иду гулять.

251:21

Speaker C

[аплодисменты] Иначе я сопротивляюсь. Ну и давайте запустим этот код. Я иду гулять. Почему мы идём гулять? Потому что и солнечно, и выходной. А мы говорим, что мы пойдём гулять только, если будет и солнечная погода, и выходной. То есть солнечная

251:43

Speaker C

погода труда. И выходной тоже правда. Всё, я иду гулять. Теперь давайте представим, что у нас дождливая погода, то есть не солнечная, но выходной. Ну, значит, Сани у нас будет Фолс. Ну, потому что у нас не солнечная погода какая-нибудь там

251:59

Speaker C

ветренная пасмурная там вообще плохая, короче. Но зато выходной. Давайте посмотрим, что будет. Запускаем. Я сопротивляюсь. Почему? Почему ты сопротивляешься выходной же? Но нет, я сказал, что я пойду гулять только, если будет и выходной, и солнечная погода.

252:15

Speaker C

Просто выходной, если. Но при этом погода плохая, там дождливая, я не пойду никуда гулять. Ну хорошо, ладно, давай, тебе будет тогда солнечная погода, но при этом будний день, не выходной.

252:26

Speaker C

Так-то пойдёшь хотя бы гулять? Ну, погода-то солнечная, что ты, пойдём гулять. Запускаем. Нет, тоже я сопротивляюсь. Почему? Потому что погода хоть и солнечная, но у нас рабочий день не выходной, никуда человек не идёт гулять. Ну почему? Потому что условие,

252:42

Speaker C

которое было задано, оно говорит, что он пойдёт гулять только, если будет выполнена и солнечная погода, и выходной. Иначе, если хотя бы одно из этих условий не выполняется, он сопротивляется. Ну, тем более, если оба условия у нас не выполняются, у нас и

252:58

Speaker C

плохая погода, ещё и рабочий день, тогда человек тоже сопротивляется, как бы, ну, тем более уж он не пойдёт никуда гулять.

253:04

Speaker C

Теперь давайте перейдём к следующему примеру. Этот я закомментирую. Теперь, допустим, мы познакомились с каким-то другим человеком и спрашиваем: "Когда ты готов с нами пойти гулять?" Он отвечает, что я пойду гулять только, если мы пойдём в компьютерный клуб.

253:23

Speaker C

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

253:46

Speaker C

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

254:06

Speaker C

мороженое. Ну понятное дело, что как бы ну тут тру, тут всё это истина. Ну понятное дело, он пойдёт гулять и компьютеры, и мороженое. Ну конечно. А теперь представим, что какое-то из этих условий не выполняется. Допустим, мы смогли найти какой-то хороший

254:19

Speaker C

компьютерный клуб, но при этом там не продаётся мороженое. Ну, мороженого, значит, у нас нету. Смотрим, что будет. Я иду гулять всё равно. Почему? Потому что нам было сказано, что человек пойдёт гулять, если там компьютерный клуб или если там

254:36

Speaker C

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

254:52

Speaker C

есть, я всё равно иду гулять. А теперь давайте представим, что мы с вами нашли, где продаётся очень крутое, вкусное мороженое, но компов там как бы нету, да? То есть это на улице какая-нибудь мороженая лавка, компов нету. Компов нету, мороженое есть. Смотрим, что

255:08

Speaker C

будет. Всё равно идёт гулять. Почему? Потому что компьютеров нету. Но мороженое-то есть. А он сказал, что ему или это надо, или это. То есть даже если что-то одно из этого будет истинным, ну, например, мороженое есть, он всё равно

255:24

Speaker C

пойдёт гулять. Давайте теперь представим, что мы и компов не нашли, и мороженого не нашли. Ну, вообще ничего нету. Просто говорим ему: "Ну, короче, ничего не нашли". Что будет? Я сопротивляюсь. И вот когда уже прямо совсем ничего нету, когда и это

255:39

Speaker C

фолс, и это фолс, и компов нету, и мороженого нету, вот тогда уже человек говорит: "Я сопротивляюсь". Сейчас мы, в принципе, с вами рассмотрели вот эту вот таблицу истинности, так называемую, на примерах из языка программирования. То есть, когда мы с вами рассматривали

255:55

Speaker C

пример с солнечной погодой и выходным, тут у нас был оператор И. То есть у нас была истина только если и первое, и второе истина. Иначе всегда был фолс.

256:07

Speaker C

Помните, этот человек, он не шёл гулять, он сопротивлялся. Даже если погода у нас плохая, но выходной, или если у нас хорошая погода, но рабочий день, он вот всегда сопротивлялся абсолютно, кроме случая, когда у нас и солнечная погода, и выходной. И вот как раз и это тру, и

256:24

Speaker C

это тру. И только тогда он шёл гулять. В остальных всех случаях он не шёл гулять, даже если одно из условилось. Ну а второй человек у нас шёл гулять практически всегда, кроме случаев, когда вообще ни одно из его условий не выполнялось. Вот если

256:39

Speaker C

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

256:55

Speaker C

неважно, что отсутствовал компьютерный клуб, если хотя бы было мороженое. И наоборот, ему было неважно, что нет мороженого, если есть хотя бы компьютерный клуб. То есть вот компьютерный клуб был, мороженого не было, но всё равно он шёл гулять. Или не

257:08

Speaker C

было мороженого, но был компьютерный клуб, и всё равно он шёл гулять. Ну и тем более, если было и то, и то, он тоже шёл гулять. Вот, собственно, эта таблица истинности, которая у нас выглядит следующим образом. Её можно легко найти

257:20

Speaker C

в интернете, она в разных интерпретациях. Суть её такова, что логическая или даёт нам true, если хотя бы одно из подвыражений true. И даёт false, если всё false. А логическая и даёт true только, если оба true, иначе даёт false в любом случае, даже если у

257:41

Speaker C

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

257:58

Speaker C

бы одно из подвыражений true. То есть тут у нас может быть на самом деле false, тут false и тут false. Так вот я их даже красным сейчас выделю. Вот это всё фс, но хотя бы одно true есть, в

258:12

Speaker C

итоге будет true, потому что это или для или достаточно, чтобы хотя бы одно было true. Причём неважно, где оно стоит.

258:19

Speaker C

Если хотя бы одно true есть, то в итоге будет true, даже несмотря на то, что казалось бы почти что всё фse. Ну а в случае с логическим и ситуация как бы у нас обратная, потому что оно будет у нас

258:31

Speaker C

true только если у нас абсолютно всё в нашем выражении true. Только тогда оно будет давать нам true. Если в и хотя бы одно будет фс, тогда сразу же в итоге будет фс, несмотря на то, что практически всё было

258:50

Speaker C

труue, вот так вот работают наши с вами логические операторы и логические операторы или Но что, если у нас выражение состоит из оператора и и из оператора или они вот в перемешку и потом или, потом опять и вот что будет,

259:06

Speaker C

как оно будет выполняться? Оно будет выполняться очень похоже на то, как это происходит в математике. То есть в математике у нас, например, а x b + c умноже на d. То есть как выполнится это выражение? Ну, сначала у нас будет

259:21

Speaker C

умножение посчитано тут и тут, а потом уже результаты этих умножений будут сложены. В принципе, в логических выражениях, в логической алгебре примерно то же самое. У нас есть оператор и и есть оператор или так вот сперва выполнятся операторы и, а потом

259:40

Speaker C

уже они будут подвергнуты оператору или то есть тут можно такие скобочки поставить. Они, конечно, ни на что не повлияют, как и скобочки в случае с математическим выражением. То есть тут, что ставь эти скобочки, что не ставь эти скобочки, всё равно выражение выполнится

259:55

Speaker C

по одинаковым правилам. Но просто для наглядности можно эти скобочки оставить. По сути, это выражение будет выполняться следующим образом. Сначала посчитается вот эта вот скобочка. Ну, создадим какую-нибудь переменну типа бул 5, и она будет равна бул 1 и бул 2. Потом у нас посчитается вот

260:14

Speaker C

эта вот скобочка. Ну, пускай это будет булше, то есть бул 3 и булче. То есть у нас в бул 5 хранится эта скобочка, результат её выражения. В булше хранится вот эта вот скобочка, результат уже её выражения. Ну и в конечном счёте X будет

260:30

Speaker C

равен бул 5 или бул 6, потому что мы сначала посчитали с вами левую скобочку, положили в бул5, потом правую скобочку положили в булшесть, и потом уже они подвергнулись операторам или а каким уже именно образом будут вычисляться эти выражения,

260:49

Speaker C

написано в этой таблице. Собственно, и у нас даёт true только, если оба true. А или даёт true всегда. Кроме того случая, когда всё false. Ну и, соответственно, чтобы там не лежало под этими переменными буll true или false, в итоге

261:05

Speaker C

от этого и будет зависеть результат нашего выражения. Есть ещё несколько вещей, о которых нам следует поговорить в контексте условных ветвлений и условных конструкций. И первый из этих вещей - это операторы больше либо равно и меньше либо равно. То есть, что это

261:21

Speaker C

вообще такое? Сейчас мы обсудим. Ну вот перед нами задача, которую мы с вами уже решали. Если игрок набрал больше десяти очков, то нужно сказать, что он красавчик. Иначе сказать ему, что нужно ещё многому научиться. Ну то есть, если

261:33

Speaker C

игрок набрал больше десяти очков, если он попал в зелёную зону, то говорим ему, что он красавчик. Ну давайте начнём писать. У нас вот наша функция main. С неё начинается выполнение программы. И дальше мы будем сталкиваться с условным витвлением. Мы будем проверять, что если

261:51

Speaker C

у нас счёт, то есть наш скор больше десяти. Если ответ да, что действительно счёт больше десяти, тогда мы говорим, что игрок [аплодисменты] красавчик. Ты красавчик.

262:09

Speaker C

Иначе, то есть, если нет, если он не набрал больше десяти, тогда нужно сказать, что необходимо ещё многому научиться.

262:18

Speaker C

[аплодисменты] О'кей. Ну, в принципе, мы это с вами уже решали в самом начале. Довольно понятная задача. А теперь представим, что изначальное условие выглядит немножко иным образом. Представим, что условие выглядит вот так. Если игрок набрал от десяти и больше очков, то нужно сказать,

262:39

Speaker C

что он красавчик, иначе что ему нужно многому научиться. То есть отличие в чём? В предыдущем условии нам нужно было говорить, что игрок красавчик, если он набрал больше десяти очков. Больше десяти, то есть от 11 и далее. А тут,

262:54

Speaker C

если игрок набрал от 10ти и больше, то есть в этот раз у нас 10 уже включается тоже в наш промежуток красавчиков. Соответственно, нам нужно такое условие, которое бы включало 10, в том числе. Не просто больше 10ти, а 10 в

263:11

Speaker C

том числе. И как раз нам тут на помощь приходят операторы больше либо равно, меньше либо равно, а конкретно первый из них. То есть как бы тогда выглядела наша программа. Ну, как обычно, наша функция main.

263:24

Speaker C

начинаем своё выполнение и потом сразу же ставим условие наше, что если счёт больше либо равен 10ти, вот таким вот образом, то есть мы могли бы с вами в целом поставить условие, если счёт больше девяти, да, тогда бы мы тоже подходили под это

263:44

Speaker C

условие. Можно было так сделать. можно было сделать, если счёт больше 10 или счёт равен 10ти, тогда бы мы и больше десяти захватывали, и 10 захватывали. Это всё можно делать. Опять же, наша задача как программиста просто на опыте понять, какой оператор лучше

264:05

Speaker C

воткнуть. Тут наиболее оптимальный, наиболее понятный логический оператор - это просто больше либо равно. Потому что у нас в условии задачи завязка именно на цифру 10. Поэтому нам отталкиваться от девятки как-то было бы не очень красиво, что там, если счёт у нас больше девяти.

264:23

Speaker C

Ну, в принципе, да, мы бы с вами тогда попали как раз в этот зелёный промежуток, десяточку бы тоже захватили, всё было бы красиво. Но так как у нас в условии задачи фигурирует цифра 10, то нам её и в условное ветвление тоже бы

264:36

Speaker C

логически более правильным было воткнуть. Ну, просто потому, что потом было бы проще вспомнить вообще наши условия задачи. Поэтому воспользуемся оператором больше либо равно. Счёт больше либо равен 10ти. Когда мы ставим вот этот вот оператор, то нам будут подходить даже десяточки. Хотя раньше,

264:53

Speaker C

когда у нас был просто оператор больше, тогда нам десяточки не подходили, но теперь у нас больше либо равно, поэтому десяточка у нас включается в промежуток.

265:02

Speaker C

Ну и, соответственно, если счёт у нас больше либо равен 10ти и у нас да, то есть true, то есть верно, то есть условие, истина, тогда ты красавчик. Ну и вот я даже скопирую, иначе тебе нужно ещё многому научиться. Но отличие у нас

265:20

Speaker C

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

265:38

Speaker C

Опять же, у нас есть какой-то скор, какой-то у нас счёт. Пускай он будет равен изначально четырём. И смотрим, у нас выполнение идёт второй задачи. Если игрок набрал от десяти и больше очков, тогда он красавчик. Ну, у нас обычное

265:51

Speaker C

самоусловие, если счёт и прямо как на схемке больше либо равно 10ти, тогда выводим. Ты [аплодисменты] красавчик. Иначе, Эл, тебе нужно ещё многому научиться. Давайте запустим нашу программу.

266:18

Speaker C

Ну, четвёрочка у нас совсем далеко в красной зоне. Тебе нужно ещё многому научиться. О'кей. Теперь давайте поставим 12. У нас счёт 12. Ты красавчик. Ну, 12 у нас явно больше как бы десятки, да? То есть явно мы в зелёной зоне. А теперь давайте

266:34

Speaker C

просто 10 поставим. Счёт 10 запускаем. Тоже ты красавчик. Почему? Потому что у нас оператор больше либо равно. То есть это условие даст истину, даст true, выполнится вот этот блок, если тут счёт больше 10 либо равен. То есть и то, и то

266:53

Speaker C

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

267:07

Speaker C

было больше либо равно, это меньше либо равно. То есть тут у нас уже наоборот будет выводиться. Ты красавчик, если счёт меньше либо равен 10ти. Ну давайте поставим тут, например, 15. Запускаем.

267:19

Speaker C

Тебе нужно ещё многому научиться. Почему? Потому что 15 у нас больше 10. Значит, это условие даёт ложь.

267:26

Speaker C

Выполняется блок эсы. Ну это сейчас совсем идёт в разрез с тем, что мы до этого рассматривали. Тут у нас наоборот говорится: "Ты красавчик за маленький счёт". А за большой счёт говорят: "Тебе нужно многому научиться". Но мы сейчас немножко отходим от нашего условия

267:40

Speaker C

задания и просто рассматриваем конкретно действие оператора меньше либо равно. Повторюсь, работает аналогично с тем, как больше либо равно, только подходят все числа, которые либо меньше, либо равны. То есть 15 оно больше, поэтому это даёт ложь. А если у нас условная

267:56

Speaker C

конструкция даёт ложь и у неё есть блокса, то этот самый блок эсы отрабатывает. Поэтому у нас выводится, тебе нужно многому научиться. Ну, если тут поставим 10, 10 равно 10, да? Ну, то есть 10 меньше либо равно 10. Ну да,

268:10

Speaker C

потому что равно. Запускаем. Ты красавчик. Ну и поставим, если пятёрочку тоже самое у нас будет. Ты красавчик.

268:17

Speaker C

Почему? Потому что 5 меньше 10. Всё. Таким образом мы с вами познакомились с оператором меньше либо равно и больше либо равно. Далее нам необходимо ознакомиться с логическим оператором неравно. Выглядит он следующим образом. восклицательный знак и потом один значок равно. Что это

268:36

Speaker C

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

268:52

Speaker C

выглядит. Нам нужно, если игрок набрал ровно семь очков, вот ровно семь очков, если у нас игрок набрал, он проиграл. Ну вот не попал вот он в зелёную зону, попал вот в такую вот маленькую красную.

269:07

Speaker C

Вот ровно семь очков он набрал, проиграл. Ну а если попал в зелёную зону, то выиграл. Как бы мы это с вами могли сделать? Ну мы бы могли проверять, что если у нас счёт меньше семи или если счёт больше семи, да? То есть если

269:21

Speaker C

меньше семи или если больше семи, нам вот и то, и то подходит. Но тогда бы нам пришлось комплексное условия строить на основе оператора или а мы можем воспользоваться оператором неравно. Как это выглядит? Ну, у нас тут наша функция

269:36

Speaker C

main, как обычно, начинает выполнение, и мы сталкиваемся с условным ветвлением. То есть, чтобы мы написали условное ветвление, то есть у нас игрок выиграл вот во всех случаях. Вот он выиграл, если он не попал в семь. То есть если

269:49

Speaker C

наш счёт не равен семи, тогда мы выиграли. Ну давайте это и напишем. Если счёт не равен семи, если это условие у нас истина, если мы действительно не равны семи, если у нас тут да, тогда ты выиграл.

270:08

Speaker C

Иначе ес у нас нет, что значит нет? Вот для этого условия это значит, что мы равны семи, потому что условие, если счёт не равен семи. Вот если счёт не равен семи, да, мы не попали в семь, мы попали в зелёную

270:22

Speaker C

зону, тогда ты выиграл. Иначе мы попали, иначе ты проиграл. Ну давайте посмотрим, как это выглядит в коде. На самом деле тут ничего особенного. Просто для начального понимания это всегда довольно трудно даётся. Вот эти вот отрицания логические, вот это неравно. Довольно

270:43

Speaker C

странно, да? То есть мы же можем на равенство сравнивать, мы же можем как-то по-другому задачу решить. Ну, вообще-то, да, можем. То есть можем посмотреть, если у нас счёт меньше семи или если больше семи, а можем просто одно неравно

270:56

Speaker C

поставить. То есть нам подходит весь промежуток, кроме семёрки. И вот если не равно семь, если мы не попали в сем, значит мы выиграли, иначе мы проиграли.

271:04

Speaker C

Ну давайте посмотрим, как это выглядит в коде. Вот наш счёт. Пускай он будет пять. И наше условие, если счёт не равен семи, тогда ты выиграл.

271:21

Speaker C

Иначе ты проиграл. Давайте запустим нашу программу. Мы выиграли. Почему? Потому что у нас счёт пять. Вот пятёрочка. Она не равна семи. То есть 5 не равно семь.

271:35

Speaker C

То есть мы не попали вот в эту проигрышную циферку. Ну всё нормально, мы У нас пятёрочка. Всё, мы не равны семи, мы выиграли. Давайте тут теперь девяточку поставим. Запускаю. Тоже ты выиграл.

271:47

Speaker C

Почему? Потому что вот девяточка - это не семь. То есть 9 не равно семь. Да, ты выиграл. Ну теперь давайте всё-таки тут семёрочку поставим, посмотрим, что будет. Ты проиграл. Почему? Потому что у нас условие счёт не равно 7. 7 не равно

272:02

Speaker C

7. Нет, 7 равно 7. Нет, мы проиграли. Вот такой вот довольно незаурядный, простой с первого взгляда, но в то же время не самый очевидный. Оператор не равно. Ну и последнее, что нам осталось рассмотреть - это логическое отрицание. Что вообще

272:20

Speaker C

такое логическое отрицание? Ну, чисто если с технической точки зрения смотреть, то работает оно следующим образом. Допустим, у нас есть какая-то переменная булевская, и она равна true.

272:31

Speaker C

Если мы в логическом выражении, в логическом условии перед этой переменной поставим восклицательный знак, то выражение даст false. Если у нас переменная наоборот равна fse и мы перед ней в логическом выражении, в логическом условии ставим восклицательный знак, то всё это выражение нам даст true. Как мы

272:53

Speaker C

это можем использовать? Ну, допустим, перед нами вот такая вот нетривиальная задача. А нам дана информация о том, подписан ли человек на YouTube канал или нет. Давайте эту информацию воспроизведём в виде переменной Subscribed. И пускай там лежит true. То

273:10

Speaker C

есть переменная Subsced будет отвечать за то, подписан ли человек на YouTube канал или нет. Напоминаю, булевская переменная. Тут может быть либо true, либо false, либо да, либо нет, либо подписан на YouTube канал, true, либо не подписан, то есть флse. О'кей. У нас

273:27

Speaker C

задача, если человек не подписан на YouTube канал, то пригласить его подписаться, а если человек уже подписан, то получается делать, ну, ничего не нужно. Хорошо, как бы мы могли это сделать? Ну, давайте я вот напишу так вот до условия и после условия.

273:47

Speaker C

Ну, это просто выводы, которые нам дадут понять, что в рамках условного витвления, чтобы мы не написали, всё равно до условия и после условия у нас будет выполняться программа линейно.

273:59

Speaker C

О'кей? Если человек не подписан на YouTube канал, то пригласить его. Мм, о'кей. То есть я могу как-то проверить, если подписан. А, то есть если подписан, мне ничего делать не надо. А вот если не подписан, то есть иначе я буду его приглашать подписаться.

274:17

Speaker C

[аплодисменты] О'кей. Я вижу, ты не подписан. Подпишись, пожалуйста. Вот так вот. О'кей. То есть мы смотрим, что если человек подписан, то ничего не делаем. Иначе, если человек не подписан, то приглашаем его подписаться. Я вижу, что ты не подписан.

274:39

Speaker C

Подпишись, пожалуйста. Ну, о'кей, давайте запустим нашу [аплодисменты] программу. Ну и видим, что у нас ничего не вывелось. У нас вывелось до условия, после условия, но само условие нам ничего не вывело. Почему? Потому что у нас subsc true. То есть человек

274:58

Speaker C

подписан, и мы проверяем, что если подписан, то ничего не делаешь. О'кей? Ну, мы ничего не сделали. Человек уже подписан. Зачем нам ему кидать приветственное сообщение с просьбой подписаться? Он же уже подписан. Теперь давайте посмотрим, что будет, если у нас

275:12

Speaker C

человек не подписан. То есть fфSE запускаю и вижу, что нам вывелось. Я вижу, ты не подписан. Подпишись, пожалуйста. О'кей. То есть в целом вот такая вот наша конструкция. Она работает, она выполняет вот это вот наше условие задачи. Но выглядит довольно

275:26

Speaker C

странно, что у нас if блок пустой, то есть пустой блок if. И мы вот надеемся на отработку этого блока Элса. И вот как раз-таки с помощью логического отрицания мы можем вот ту же самую логику реализовать более красиво. Как это

275:41

Speaker C

выглядит? Смотрим. Если не подписан, тогда я вывожу вот это вот. Иначе я ничего не делаю. Всё, логика программы осталась той же самой. Я буду выводить вот этот вот текст на экран только если не подписан. То есть как вообще это

276:01

Speaker C

читается. Я поставил восклицательный знак. Напоминаю, восклицательный знак - это есть наше самое логическое отрицание. Если в переменной Subscribed лежит false, и я перед этой переменной, в которой лежит false, в логическом условии поставлю восклицательный знак, то выражение вернёт true.

276:20

Speaker C

Соответственно, если я не подписан, тогда это выражение вернёт true, и я выполню вот этот вот вывод. Если у меня в переменной subscrited наоборот изначально будет true, то в этом выражении я перед true буду ставить восклицательный знак. Всё выражение нам

276:37

Speaker C

вернёт false. Ну, соответственно, это не выполнится. Давайте проверим, как это работает. Вот у нас subsced. То есть подписан. Запускаю программу и не выявилось ничего, потому что у нас человек уже подписан. Нам, ну, не нужно ничего выводить. Давайте теперь фс, то

276:53

Speaker C

есть не подписан. запускаю и вижу, что вывелось предложение подписаться. На самом деле, если читать вот эти вот логические отрицания при помощи этой таблицы, то иногда можно запутаться, потому что довольно неочевидно вот это вот если true, не false. Гораздо проще

277:11

Speaker C

изначально булевскую переменную обозвать как-нибудь понятным языком. Ну вот, например, как у нас subscribed, то есть подписан ли, а потом читать вот эти вот условные конструкции прямо как книгу.

277:23

Speaker C

Что тут написано? если не подписан, то есть если не подписан, тогда выполни вот этот вот блок кода. Ну, иначе мы ничего не делаем. Всё это и есть то самое наше логическое отрицание. Стоит, конечно же, уточнить, что при этом значение самой

277:39

Speaker C

переменной, оно, ну, не меняется никак, потому что это логическое отрицание, оно является частью логического выражения, но при этом мы не меняем значение самой переменной. То есть давайте я выведу до условия значение переменной вот это вот subscribed и после условия

277:55

Speaker C

тоже запускаю программу. И я вижу, что у меня что до условия false, что после условия fфse. Хоть я здесь в условном выражении и сделал логическое отрицание, я результат этого выражения не перезаписал в переменную. Я просто результат этого выражения использовал в

278:13

Speaker C

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

278:30

Speaker C

обрабатывать в блоке Элса, как у нас было при первом подходе к решению задачи. Ну, согласитесь, выглядит довольно странно и может даже кого-то запутать.

278:40

Speaker C

А такой вариант, он и короче, и красивее, и сразу же мы понимаем, что написано, и гораздо меньше вероятность [музыка] запутаться. Следующая наша тема - это циклы в программировании. Мы посмотрим вообще, что такое циклы, для чего они нужны и как используются. Ну, для начала

278:59

Speaker C

давайте вообще разберём значение слова цикл в обычной речи, то есть в нашей обычной жизни. Ну вот у нас есть цикл сезонов года, например, то есть что он вообще из себя представляет. У нас сначала зима, потом идёт весна, потом

279:13

Speaker C

идёт лето, потом идёт осень, и проходит год. И снова начинается то же самое: зима, весна, лето, осень. И потом опять то же самое. То есть циклическое повторение какого-то алгоритма. В данном случае у нас алгоритм смены сезонов года. То есть первое у нас это с вами

279:31

Speaker C

зима, потом из зимы становится весна, потом из весны становится лето. И из лета у нас становится осень, а потом из осени опять становится зима. То есть у нас происходит зацикливание наших сезонов года. Они как бы крутятся по кругу, повторяя одно и то же из раза в

279:51

Speaker C

раз. То есть зима, весна, лето, осень, заново. Зима, весна, лето, осень, заново. Поэтому это и называется цикл.

280:00

Speaker C

Цикл повторения какого-то алгоритма несколько раз. То есть наш алгоритм - это зима, весна, лето, осень. просто наш год, наши сезоны года. А цикл - это потому, что они повторяются. Собственно, вот цикл сезонов года. Ещё один пример - это цикл воды в природе. Ну, его ещё

280:18

Speaker C

называют круговорот воды в природе. Что он из себя представляет? У нас есть какой-то водоём. Этот водоём под действием лучей солнца испаряется, и вода, которая была в водоёме, превращается в облако. Потом облако становится очень большим и превращается в тучу. Потом туча сама уже становится

280:35

Speaker C

слишком большой, не может в себе удерживать всю воду и проливается дождём. Этот самый дождь опять попадает в водоём. И таким образом у нас зацикливается вода в природе. То есть давайте это опишем. У нас первым делом вода находится в каком-то водоёме. Я

280:53

Speaker C

вода в водоёме. Потом я испаряюсь, потому что вода у нас испаряется ну под действием солнца. Я испаряюсь под действием солнца. Потом я становлюсь облаком.

281:12

Speaker C

Потом я становлюсь тучей. Потом туча у нас проливается дождём. Я проливаюсь дождём. И так дальше. Мы после того, как проливаемся дождём, снова становимся водой в водоёме. Я вода в водоёме. И, соответственно, дальше мы будем просто повторять то же самое. Там у нас если

281:37

Speaker C

седьмой пункт - это я испаряюсь по действиям солнца и так далее. То есть у нас весь алгоритм, он заканчивается пятым пунктом, а потом он опять зацикливается. То есть у нас опять происходит цикл, только в этот раз уже не сезонов года, а воды в природе. То

281:54

Speaker C

есть у нас была вода в водоёме, она испарилась под действием солнца, стала облаком, потом стала тучей, потом пролилась дождём. И после того, как она пролилась дождём, она опять стала водой в водоёме. То есть у нас опять же почему

282:08

Speaker C

это всё называется именно цикл воды в природе? То есть у нас есть какой-то алгоритм, и он повторяется несколько раз, но сам алгоритм у нас одинаковый. И из-за того, что он повторяется, это называется циклом. То есть цикл - это

282:22

Speaker C

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

282:35

Speaker C

Алгоритм может быть самый простейший, а может быть очень сложный, но если он повторяется из раза в раз, то это цикл.

282:42

Speaker C

Ну теперь давайте рассмотрим циклы в рамках языка программирования. Создам main Goфайл, объявлю главный пакет, объявлю главный кусок кода, главную нашу функцию. И тут сразу же покажу вам цикл. Сейчас ничего не будет понятно, но приготовьтесь, я буду объяснять. for I = 1. Iше либо равно п i

283:07

Speaker C

+ и тут мы будем выводить на экран Hello World. Сохраняю. Что это вообще за такое чудо?

283:17

Speaker C

Что тут за фигня вообще написана? Совсем непонятно. Ну давайте разбирать. И всё, что нам знакомо - это вывод на экран Hello World. Вот это всё, что мы знаем.

283:27

Speaker C

А давайте программу запустим, посмотрим, что вообще будет. Опа, пять раз вывелась на экран Hello World. 1 2 3 4 5. О, как. А мы всего один раз написали Hello World, но вывелось пять. А давайте тут добавим что-нибудь. FMT Printen. Вот у нас было

283:49

Speaker C

Hello World. А тут я ещё выведу лампочка. И после этого ещё выведу просто пустую строчку вот таким вот образом, чтобы у нас было разделение наших выводов. То есть вот это просто пустая строчка, но так как она выводится в принтелене, то

284:05

Speaker C

всё, что вот это нам даст - это перенос курсора на новую строку. Ну давайте запустим.

284:12

Speaker C

Опа. Hello world, лампочка пустая строка. Hello world, лампочка пустая строка. Hello world, лампочка пустая строка. Hello world, лампочка, пустая строка. Hello World лампочка пустая строка. То есть то, что у нас написано вот в этих вот скобочках, в теле цикла,

284:30

Speaker C

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

284:46

Speaker C

конструкции. Всё это будет повторяться несколько раз, потому что это цикл тот самый, который мы с вами обсуждали, там цикл сезонов года, цикл воды в природе, это тот же самый цикл. Вот наш описанный алгоритм, который будет повторяться. А повторяется он, потому что находится в

285:03

Speaker C

теле цикла. Теперь давайте более подробно разберём вообще синтаксис объявления вот этого самого телоцикла. Ну, для того, чтобы объявить цикл, нам нужно написать for. То есть for - это название цикла. Циклфор. В других языках программирования есть другие циклы, но в

285:19

Speaker C

GoН нам повезло, у нас только цикл for и всё. То есть for нам нужно написать для того, чтобы объявить цикл, начало цикла.

285:29

Speaker C

Дальше у нас давайте поподробнее рассмотрим какой-то i = 1, i меньше либо равно п i +. Ну давайте смотреть. Когда мы с вами пишем for, то язык программирования понимает, что сейчас будет объявление цикла и предоставляет нам три секции в

285:48

Speaker C

объявлении цикла, которые мы с вами должны заполнить. То есть всё, что разделено точкой запятой - это секция.

285:54

Speaker C

Первая секция, вторая секция, третья секция. Значит, первая секция, давайте я буду вот так вот писать. Первая секция - это объявление переменной. Вот наша первая секция. И вот это объявление переменной.

286:13

Speaker C

Вот как она выглядит. I = 1. То есть тут у нас в этой секции создаётся переменная i. Ну, на самом деле, этот синтаксис нам уже знаком, когда мы с вами создавали ту же переменную скор, там, например, скоore = 5. То же самое. Объявление

286:28

Speaker C

названия переменной. Двоеточие равно, чтобы сказать, что мы создаём новую переменную. И справа значение, которое мы в неё кладём. Ну, в данном случае у нас I1, как у нас было в скоро, мы клали пять, тут мы просто в I кладём один.

286:41

Speaker C

О'кей, создали какую-то переменную I. Дальше у нас вторая секция. Вторая секция, условие, при котором цикл будет выполняться. Это значит, что точно так же, как мы с вами в условных конструкциях проверяли, больше, меньше, равно, меньше либо равно, больше либо

287:06

Speaker C

равно, вот тут условие, при котором цикл будет выполняться. Ну, мы это чуть попозже разберём. Сейчас, ну, не совсем понятно, как это вообще будет происходить, потому что у нас же i1, а тут i меньше либо равно пяти. Ну, типа,

287:19

Speaker C

о'кей, будет выполняться и всё. И типа, и что? Бесконечность он будет выполняться. Сколько он будет выполняться-то? Непонятно. Дальше у нас с вами третья секция, это изменение от одной итерации к другой. Что такое итерация вообще?

287:40

Speaker C

Итерация - это один прогон всего алгоритма внутри цикла. То есть, если мы вернёмся к нашим примерам, то вот я вода в водоёме, я испаряюсь по действиям солнца, я становлюсь облаком, я становлюсь тучий, я проливаюсь дождём.

287:53

Speaker C

Это одна итерация. То есть просто один прогон вот этого алгоритма, который у нас заключён в цикле - это одна итерация. Потом уже зацикливание этой итерации - это и есть цикл. Но сама итерация - это просто единовременный прогон вот этого алгоритма.

288:10

Speaker C

Соответственно, в данном случае у нас одна итерация - это вывод Hello World, лампочка и пустой строчки. Вот это одна итерация. Потом, ну, то есть вот у нас она в консоли. Вот наша одна итерация.

288:22

Speaker C

Вот вторая итерация. Вот третья итерация. Вот четвёртая итерация. Вот пятая итерация. То есть одна итерация - это один прогон телоцикла. И это наша третья секция - это указание языку программирования, как нужно менять переменную нашу, которая вот здесь объявлена, от одной итерации к другой.

288:42

Speaker C

Что это значит? Ну, I++ мы помним, что это просто увеличить на один. То есть это то же самое, что и I = I + 1. То есть это то же самое. На самом деле сейчас, в принципе, должно быть вообще ни хрена непонятно. Это

288:56

Speaker C

нормально. Но сейчас давайте просто смиримся с фактом, что у нас есть цикл. Он повторяется какое-то количество раз.

289:04

Speaker C

Давайте я оставлю тут только вывод Хуралда и ещё раз запущу нашу программу. Вот у нас пять раз выявился Hello World. Для того, чтобы более подробно разобрать, что вообще тут происходит, я подготовил следующие схемки. Тут у нас выделены какие-то

289:21

Speaker C

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

289:39

Speaker C

выводим Hello World на экран, потому что это всё, что у нас написано в телецикла.

289:43

Speaker C

Так вот, давайте посмотрим, что у нас тут происходит. Значит, первая секция объявления переменной. Мы объявляем i = 1. Вот i = 1. И я тут нарисовал график наших i, прямую линию наших i. И тут мы видим, что у нас есть i и есть разные

290:03

Speaker C

значения. То есть изначально мы i задаём один. Вот здесь вот пишем i = 1. Ну и вот я выделил зелёненьким то, что i у нас равно 1. Хорошо. Дальше у нас условие i меньше либо равно пяти. То есть это условие, при котором цикл будет

290:20

Speaker C

выполняться. Вот наша самая пятёрочка. Вот она здесь красным выделено. Ну и, соответственно, вот у нас I++. Теперь я хочу обратить ваше внимание, что у нас пронумерована последовательность выполнения нашего цикла. Вот она. 1 2 3 4 5 6 7 8 9 10 11 12. Ну и так до 24. То

290:41

Speaker C

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

290:47

Speaker C

Значит, первым делом у нас в цикле создастся переменная i, которая равняется единице. Ну и, соответственно, вот наш график переменных I. Вот она наша i, которая равна один. Дальше сразу же после того, как в цикле у нас создалась переменная, сразу же идёт

291:05

Speaker C

проверка. Проверка условия, при котором цикл будет выполняться. У нас сразу же смотрится I у нас меньше пяти. Ну, вообще-то, да, потому что у нас I1. Мы это с вами сами написали в предыдущей секции. И i меньше п. То есть, ну, 1

291:21

Speaker C

меньше либо равно пяти, да? То есть вот где один у нас, вот где пять вообще. То есть, да. Если да, это значит, что условие у нас истинное, значит, цикл будет выполняться. Ну, значит, как только мы поняли, что у нас цикл будет

291:35

Speaker C

выполняться, сразу же идёт выполнение тела цикла. То есть у нас выводится на экран Hello World. То есть создали переменную i, присвоили ей какое-то значение, сразу же проверили условия, будет ли цикл выполняться, узнали, что цикл будет выполняться, вывели на экран

291:51

Speaker C

Hello World. После того, как тело цикла заканчивает своё выполнение, когда мы заканчиваем первую итерацию, у нас происходит третья секция, вызывается, а в третьей секции мы просто увеличиваем i на о. То есть у нас уже идёт переход ко второй итерации. У нас i уже равно 2. То

292:09

Speaker C

есть вот мы в конце первой итерации увеличили i на x 1. Ну то же самое, что i = i + 1 увеличили i x на x 1. I стало 2, потому что оно было вот один, а теперь стало двоечкой. Всё, у нас

292:21

Speaker C

началась новая итерация. I = 2 уже в ней, потому что на предыдущей итерации мы прибавили i. I = 2. То есть вот эта секция с объявлением, переменной и присваиванием, она уже никакого эффекта не имеет. Она имеет эффект только на

292:37

Speaker C

самой первой итерации, когда мы первично задаём значение переменной. Дальше уже вот это присваивание, оно не будет играть роли, и у нас i не будет становиться единицей. Один раз мы вначале задали единицу, а потом уже мы к этой первой секции не будем

292:54

Speaker C

возвращаться, пока, в принципе, тело цикла у нас не завершится. То есть только в самом начале вот эта секция имеет вес. Она создаёт переменную и кладёт туда какое-то значение. Ну, значит, положили туда единичку, мы запомнили, вывели первый раз Hello

293:07

Speaker C

World, I++. Всё, переходим ко второй итерации. У нас I уже двоечка. Ну, потому что мы на предыдущей итерации прибавили. Вот Iвоечка. И мы опять уже проверяем, I меньше либо равно пяти. Ну 2 меньше либо равно пяти, да? Вот где

293:23

Speaker C

два у нас, вот где пять. Ну да, опять, да. Значит, мы опять будем выполнять тело цикла и уже второй раз выводим на экран Hello World. После того, как тело цикла у нас на второй итерации завершилось, мы опять прибегаем к

293:38

Speaker C

третьей секции и опять изменяем переменную I на о. Теперь у нас I стало уже троечкой. То есть у нас каждый раз, когда мы заканчиваем предыдущую итерацию, мы как-то меняем нашу переменную. И перед тем, как перейти к новой итерации, каждый раз цикл будет

293:58

Speaker C

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

294:19

Speaker C

условие станет ложным, как только вторая секция станет ложной, сразу же завершится весь цикл. Ну давайте смотреть. Мы с вами уже вывели Hello World один раз, вывели второй раз, прибавили I. I стала трём у нас равна, ну, смотрим, I у нас равна 3. До пяти у

294:36

Speaker C

нас ещё далеко. Смотрим, I меньше либо равно пяти. 3 меньше либо равно пяти, да? Ну, как бы вот у нас три, вот у нас пять. То есть 3 меньше либо равно пяти, да? Опять выполняем тело цикла. Ну, у

294:47

Speaker C

нас всё тело цикла - это просто вывод на экран. Опять прибавляем i, то есть оно уже становится четыре, и переходим к новой итерации. Смотрим, у нас четыре меньше либо равно пяти, да? Опять выполняем тело цикла. Опять выводим на

295:01

Speaker C

экран уже четвёртый раз Hello World. И после этой выполненной итерации в конце прибегаем к третьей секции, а там у нас I++. Ну, соответственно, у нас I стало 5 равно. Вот мы прямо попали в пятёрочку.

295:14

Speaker C

I меньше либо равно пяти. 5 меньше либо равно пяти. Да. Ну, потому что 5 меньше либо равно. Равно. Да. Значит, всё, мы отвечаем истиной. Опять выполняется тело цикла. Опять мы выводим уже пятый раз на экран Hello World. И опять прибавляем I.

295:33

Speaker C

То есть мы вывели пятый раз на экран Hello World. И вот в конце этой итерации мы опять выполнили третью секцию и опять прибавили к i1диницу. I стало равно шести.

295:45

Speaker C

Мы смотрим, I у нас 6. Вот I. Вот наше условие, то, что I должно быть меньше либо равно пти. 6 меньше либо равно пяти. Нет, больше. Всё. Как только мы с вами столкнулись с тем, что наше условие из второй секции не выполняется, тело

296:04

Speaker C

цикла сразу же завершается после этого. Всё это объясняет, почему же у нас был вывод Hello World на экран пять раз. Да потому что мы тут циферку пять написали, задали изначально один и на каждой итерации прибавляли единичку. Это означает, что у нас сначала была

296:24

Speaker C

переменная i равна 1, потом равна 2, потом равна 3, потом равна 4. На каждой итерации потом равна 5 и потом равна. И то есть вот эти все i у нас подходили под условие из второй секции и мы выводили

296:41

Speaker C

на экран, а последняя не подошла под условия, и мы сразу же завершили цикл, даже не стали выводить ничего на экран.

296:49

Speaker C

Соответственно, если мы тут с вами напишем, например, троечку и запустим программу, то Hello World выведится три раза по тем же самым причинам, потому что у нас изначально I один 1 меньше т.

297:02

Speaker C

Да, выводим на экран. I стало 2. 2 меньше либо равно 3. Да, выводим на экран. I стало 3. Меньше либо равно 3. Да, выводим на экран. А стало 4. Четыре меньше либо равно тх нет. Всё, завершили цикл. Ну и, соответственно,

297:19

Speaker C

можно показать, как это вообще происходит до и после цикла. Что происходит? Вот я тут напишу до, а тут я напишу после. Запускаю. Ну и вот видите, у нас до, потом три раза выполняется тело цикла, и после мы выводим.

297:40

Speaker C

Соответственно, тут мы можем создавать переменные с любыми названиями, присваивать им любые значения, ставить любые условия, делать им любое изменение от одной итерации до другой. Но цикл он всегда будет смотреть на то, что мы написали в каждых трёх секциях, и

297:57

Speaker C

выполнять беспрекословно то, что мы тут укажем. Сейчас мы с вами столкнёмся с таким понятием воли неволей, как область видимости переменных. Что это такое? То есть, если мы в каком-то куске кода объявим переменную, это значит, что она будет видна только в этом куске кода. В

298:18

Speaker C

другом месте этой переменной уже не будет видно. Ну давайте я буду выводить вот тут вот в нашем телецикла помимо Hello World ещё через запятую эту самую переменную I. Ну почему нет? Мы же помним, что мы можем вот так вот

298:31

Speaker C

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

298:42

Speaker C

Выведем её тут. Ну, запускаю программу. Ну, в принципе, ожидаемо, да? Мы помним, что у нас на первой итерации i = 1, потом i у нас прибавляется в конце уже тело цикла. После того, как тело цикла выполнилось, после того, как

298:56

Speaker C

выполнилась очередная итерация, прибавляется I, становится 2. Выводим на экран Hello World 2. I прибавляет, становится три. Три меньше либо равно трёх? Ну да, условие выполняется истино.

299:07

Speaker C

Опять выводим на экран третий раз, потом i становится четыре и всё. То есть, потому что 4 > 3. Это условие уже ложено, и тело цикла у нас завершается.

299:17

Speaker C

А теперь давайте попробуем. Ну, тут-то мы же создали переменную i, правильно? Ну, мы можем, значит, её дальше использовать. Ну, я, например, хочу вот тут вот присвоить Е5. Смотрим, что-то ругается. Undefined I, то есть неопределённая I. Почему неопределённая?

299:33

Speaker C

Вот же мы её как бы создали. Почему нет? А может я её на экран могу вывести? Нет, тоже. То есть тут уже почему-то язык программирования не знают, что такое I, хотя ещё в теле цикла знал. Так вот, это та самая

299:49

Speaker C

область видимости переменных. Когда мы создаём какую-то переменную в цикле, то видна будет эта переменная и существовать она будет только в теле этого самого цикла. То есть эта переменная i, она создастся, когда язык программирования дойдёт до этой строчки, и она удалится. когда язык

300:10

Speaker C

программирования пойдёт дальше. То есть переменная i она существует только в рамках вот этого куска кода. Это её область видимости. Эта переменная, она не видна ни до, ни после. Её просто не существует здесь. Она существует только в рамках этого цикла. Мы даже можем

300:30

Speaker C

внутри тела цикла. Ну это, в принципе, кусок кода тела цикла. Мы тут можем делать что угодно, просто оно будет повторяться несколько раз. Мы можем тут даже создать нашу переменную score.

300:40

Speaker C

Давайте это сделаем. Скор = 5. И хочу её тоже вывести на экран. Ну вот скор. И вот так вот скоe.

300:49

Speaker C

Сохраняю. И я не могу программу запустить, потому что у меня ошибка. Я использую несуществующие переменные до и после. Ну давайте я как бы удалю их.

300:57

Speaker C

Казалось бы, вот мы тут создали переменную внутри тела цикла. Давайте запустим программу. И она, в принципе, работает. Для того, чтобы мы с вами отдельные итерации могли различать. Тут я ещё сделаю пустой вывод на экран, чтобы просто была пустая строчка

301:10

Speaker C

дополнительная в конце каждой итерации. Смотрим, у нас до вот начинается наша первая итерация. Hello World 1, ну потому что I1 score 5. Ну мы скоore от одной итерации к другой вообще никак не меняем, поэтому он у нас создаётся один раз, в него кладётся

301:30

Speaker C

значение пять, и потом мы это самое значение выводим. Ну и, собственно, у нас скор он создаётся в начале этой итерации и удаляется в конце итерации.

301:40

Speaker C

Ну, это мы можем с вами проверить, что у нас после цикла скоро удаляется, потому что мы его тут опять же никак не сможем использовать. Ну, скоore, вот он наш скоore, как бы, да. А почему опять undefined? Что это значит? что в

301:54

Speaker C

двадцать пятой строке переменный скор уже не существует, потому что её область видимости определена куском кода, в которой эта переменная создавалась. Мы создали эту переменную в теле цикла, и там она и существует, там она и помрёт.

302:11

Speaker C

Ещё будет сейчас довольно забавный момент. Смотрите, мы в конце итерации прибавим к скор, ну, троечку, например.

302:19

Speaker C

Ну, тут понятно, скор у нас не существует, но тут-то он существует в теле цикла. Давайте запустим программу. А, всё равно скор каждый раз равен пяти. Но мы же тут изменили как бы его. Должно быть, мы скор пять создали

302:34

Speaker C

на первой итерации, потом прибавили три, он стал восемь. Да, потом пошли, вывели, тут должно быть восемь. Потом плют, опять должно быть 11.

302:45

Speaker C

А не тут-то было, как я сказал, переменные, которые созданы в телецикла, они создаются там, где создаются в этом самом телецикла, и умирают в конце этого цикла. Что это значит? Что мы тут создали на первой итерации, где у нас

303:02

Speaker C

Hello World 1, эту переменную Score. В конце прибавили ей троечку, она стала восемь. Но тут же эта переменная, после того, как она стала восем, она умерла. И на второй итерации, где у нас Hello World 2, эта переменная скор заново

303:21

Speaker C

создаётся. То есть это уже другая переменная score. Это не та же самая переменная скор, что была на предыдущей итерации. Поэтому нужно мыслить про вот этот кусок кодов телецикла просто как про повторяющийся код, который сверху вниз повторяется. Если мы тут заново

303:40

Speaker C

объявляем переменную скор, то она заново создастся. Старая переменная в конце предыдущей итерации удалится, и тут мы уже будем работать с абсолютно новой переменной. Ну давайте для чистоты я вот здесь вот а сразу же прибавлю к ней три и будем выводить её на

304:00

Speaker C

экран. Видите, восемь. Почему создали переменную скор? Положили в неё пять. К пяти прибавили три, стало восемь. И мы это восемь выводим на экран. Но в конце нашей итерации наша переменная score удаляется из памяти, она исчезает. И в начале следующей итерации, где вот у нас

304:19

Speaker C

был Hello World 1, первая итерация, вторая итерация Hello World 2, на второй итерации переменная Score создаётся заново. Это уже другая переменная Score.

304:29

Speaker C

Это уже не та переменная Score, что мы знаем. Это новая. И на каждой итерации вот этот весь код будет выполняться заново. В том числе заново будут создаваться все переменные. И что не менее важно, в конце итерации эти переменные будут удаляться, и их нельзя

304:47

Speaker C

будет использовать вне цикла. То есть мы переменную скор объявили. Тут мы не можем её использовать ни до, ни после. Везде будет нам говорить, что этого не существует. Какой-то непонятный скор. Почему? Да, потому что он родился, вырос и помер в нашем теле

305:07

Speaker C

цикла. Это область видимости переменной скор. Область видимости переменной ограничена тем куском кода, в котором мы создали эту самую переменную. То есть, если мы, например, создали бы переменную в мейне, да, давайте я вот тут вот напишу, например, у нас будет

305:23

Speaker C

какая-нибуд переменная number, просто чиселка вот 999. Как мы помним, область видимости переменной ограничена куском кода, в которой эта самая переменная создана. То есть, так как мы создали с вами number в куске кода, то есть мы можем даже навести на переменную, просто

305:40

Speaker C

нажать на неё, и нам сразу же подсветятся скобочки того куска кода, в который мы с вами создали переменную. То есть вот мы создали переменную number в куске кода. Мы можем навести на него и сразу подсвечивается. Если мы нажмём на

305:54

Speaker C

переменну скор, то нам сразу подсветится кусок кода, который ограничивает тело цикла, что нам говорит о том, что область видимости этой переменной - это тело цикла, а область видимости переменной number - это вся функция main, весь кусок кода. Что это значит?

306:12

Speaker C

Что мы этот самый numberр можем использовать и до, и после цикла, и прямо в цикле мы можем его тоже использовать. Почему? Потому что у нас создаётся в функции main. И number у нас умрёт только, когда функция main закончится, но не раньше. А тело цикла и

306:33

Speaker C

в принципе цикл - это просто часть этой функции main. Поэтому мы можем и выводить на экран наш. Давайте запустим программу. Вот он наш намр. И он вполне работает в телецикла. Также мы можем его на каждой итерации вручную менять. Ну, например, в

306:51

Speaker C

конце мы будем делать number плюс плюс тоже number п. Запускаем. И как мы видим, у нас на первой итерации numberр 999. Потом в конце мы сделали плюс плюс. На новой итерации numberр уже 1.000, потом 1.1 и в конце он ещё раз прибавился 1.2. Это

307:12

Speaker C

область видимости переменных. Я понимаю, что сейчас, наверное, вообще сложно это всё удержать в голове. большой поток информации, но тут решает только практика. Оно всё само в голову не залезет. Это нужно в голову запихивать.

307:27

Speaker C

Нужно сидеть, тыкаться, разные тут условия ставить, разные тут превращения делать. То есть мы с вами тут могли бы вообще делать не плюс-плюс даже. Давайте я удалю всё лишнее. А, например, плюс равно 2. Ого, что это значит? И вот тут

307:45

Speaker C

вот я поставлю десяточку. Давайте будем выводить. У нас изначально была переменная i = 1.

307:52

Speaker C

А преращением, то есть изменением этой переменной от одной итерации к другой мы указали не плю1, а плюд 2. Ну и, соответственно, у нас было один, потом стало три, потом стало пять, потом стало семь, потом стало девять, потом стало

308:06

Speaker C

11, и вот это условие не выполнилось, и у нас цикл закончился. То есть тут можно, да, хоть умножение оставить. I x = 2. Ну и, соответственно, тут у нас будут степени двойки, потому что 1, потом 1 x 2 стало 2, 2 x 2 стало 4, 4 x 2 стало 8

308:24

Speaker C

и так далее. Тут вообще, что вы сможете придумать, то и будет. Это довольно сложная тема, её нужно практиковать.

308:33

Speaker C

Сначала попробуйте простой примерчик, где вы там три раза выводите на экран с помощью цикла Hello World. Потом попробуйте изменить это число, попробуйте вывести саму переменную, поиграться с областью видимости. Нужно вот эти циклы почувствовать. Попробуйте посоздавать переменные в них. Попробуйте

308:51

Speaker C

посоздавать переменные в мейне и поиспользовать эти переменные внутри цикла. Это всё нужно прочувствовать. Нужно свои мозги настроить на то, что цикл - это какая-то повторяющаяся операция из раза в раз. У нас тело цикла повторяется из раза в раз. Но для чего

309:08

Speaker C

нам вообще, блин, нужны эти циклы? Зачем нам вот это вот повторение, вот эта вот беготня по кругу? Давайте снова вернёмся к нашей игре Fl Bir, вспомним, в чём она заключается. В том, что у нас есть птичка, уточка, и эта уточка пролетает

309:22

Speaker C

через зелёные трубы. Помните, мы с вами писали симуляцию этого всего, когда мы писали: "Я пролетаю через трубу, мой счёт увеличивается на один". Ну и так далее. Теперь давайте заново это же сделаем. Только в этот раз я вот приготовил такие символы. То есть вот

309:38

Speaker C

эта зелёная батареечка - это типа труба будет, а вот эта уточка - это та самая птичка, которая у нас вофпеst пролетает.

309:45

Speaker C

Ну вот это вот я всё сотру и начну писать наш код, то есть нашу симуляцию этой игры Flppy Birds. Ну сперва, что у нас происходит, это приветствие типа Get Ready, кто помнит.

309:57

Speaker C

Ну условно говоря, приготовьтесь. Get ready. Потом FMT Printl. Вы подлетаете к трубе. А теперь давайте ещё и напишем иллюстрацию того, как мы подлетаем к трубе. То есть у нас есть птичка, и она подлетает к трубе. То есть труба - это будет две вот такие вот

310:16

Speaker C

палочки. Это как бы труба. Левая часть трубы и правая часть трубы. После этого выведем ещё пустую строчку, чтобы как-то разделить наши эти выводы, чтобы они все слитно не были. Прямо вот строка за строкой.

310:30

Speaker C

Дальше вы пролетаете через трубу. Значит, как это [аплодисменты] выглядит? Скопируем нашу птичку, и птичка будет вот прямо внутри трубы. Вот это значит, что птичка пролетает через трубу. Ну и опять выведу пустую строчку, чтобы разделить наши действия в консоли,

310:53

Speaker C

чтобы они все не сливались строчкой за строчкой. И потом у нас последнее - это вы пролетели через трубу. Ну и, соответственно, покажем, как наша птичка пролетела успешно через эту трубу. Вот.

311:07

Speaker C

То есть подлетает к трубе, пролетает через трубу и пролетела. Ну нам ещё, наверное, тут нужен счёт, потому что без счёта зачем нам летать через трубы?

311:17

Speaker C

Создадим переменную скор. Изначально у нас ноль. Ну вы подлетаете к трубе, вы пролетаете через трубу, вы пролетели через трубу. Когда мы с вами пролетаем через трубу, тоже пустой вывод оставлен.

311:31

Speaker C

Мы увеличиваем наш счёт на один. Ну, скоore плюс плюс. И выводим наш [аплодисменты] счёт. Счёт. И тут скор. И после этого опять же выведу пустую строку, чтобы разделить наши выводы. Ну, давайте запустим вообще программу теперь и посмотрим, что случилось.

311:53

Speaker C

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

312:12

Speaker C

пролетели через трубу. Счёт один. Давайте ещё подпишем наши трубы. Вы подлетаете к трубе. И тут мы ещё напишем один. Вы пролетаете трубу один. Вы пролетели через трубу один. Просто чтобы мы знали, через какую трубу мы вообще пролетаем по счёту. Но в данном случае у

312:28

Speaker C

нас изначально счёт ноль. Мы подлетаем к первой трубе, мы пролетаем через первую трубу. И когда мы пролетели через первую трубу, у нас счёт стал единичка. Даже в начале я хочу вывести для наглядности этот счёт.

312:45

Speaker C

Счёт ср. Воттрейде счёт ноль. В начале пролетели через трубу. Счёт один. Ну, так как у нас симуляция флапибрда, флапибрд состоит не только из одной трубы, мы, наверное, захотим это всё повторить несколько раз. Ну, соответственно, пролететь через несколько труб. Значит, нам нужно это

313:02

Speaker C

всё скопировать. Ну, кромерейди, потому что понятно, это приготовление. Вот мы подлетаем к трубе. Только в этот раз мы уже будем подлетать не к первой трубе, а ко второй. Я тут просто поставлю веде циферку два. Сохраняю и вывожу на экран.

313:17

Speaker C

Get ready. Вы подлетаете к трубе один. Вы пролетели трубу один, счёт один. Потом то же самое с трубой два, счёт два. И нам, чтобы просимулировать, ну, к примеру, 10 этих труб, нам нужно 10 раз это всё скопировать. Сразу видно, что код

313:36

Speaker C

становится какой-то очень некрасивый и слабочитаемый. То есть, если мы тут скопируем ещё раз эти все выводы, вот так вот. 1 2 3 Это вообще уже становится сложно читать какие-то выводы постоянные. Что-то тут счёт какой-то мелькает. А если мы захотим 50

313:56

Speaker C

труб таких вывести, ну уже, конечно, это будет совсем грустно. Но мы вспоминаем, что мы с вами знаем циклы. А циклы - это повторение какого-то алгоритма несколько раз, столько раз, сколько мы захотим.

314:10

Speaker C

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

314:29

Speaker C

создадим наш цикл. Мы уже умеем. I = 1, I меньше либо равно 3, I + Вот объявили цикл, все три секции. Создаём переменную, задаём условия до тех пор, пока цикл выполняется. и задаём изменения переменной от итерации к итерации. Это всё можем просто

314:49

Speaker C

скопировать и вставить тело цикла. Давайте попробуем сейчас посмотреть, что вообще у нас получилось. То есть мы взяли в тупую всё, что у нас было написано, и вкрячили в цикл. Давайте посмотрим. Трейди счёт ноль. Вы подлетаете к трубе один. Вы пролетаете

315:07

Speaker C

через трубу один. Счёт один. А потом опять счёт ноль. То есть мы всю игру, включая Трейди и создание счёта, запихнули в цикл. Но если так чуть-чуть подумать, то вот этотреди самая первоначальное нам нужно как бы только в самом начале вывести.

315:30

Speaker C

Нам не нужно это несколько раз выводить. И счёт нам тоже нужно не на каждой итерации заново создавать. Нам нужно один раз эту переменную создать, а потом уже её менять. Потому что, если мы её внутри телоцикла будем создавать, она на

315:45

Speaker C

каждой итерации будет обнуляться. И мы это как бы с вами видим, да. У нас типа атреди счёт ноль, счёт один, потом опять getтрейди счёт ноль, потом опять getтрейди счёт ноль. То есть у нас эта переменная скор, несмотря на то, что мы

315:58

Speaker C

её как бы вроде увеличиваем на один, она всё равно остаётся ноль, потому что она с каждой новой итерацией пересоздаётся, и у нас какая-то фигня получается. Ну, опять же, если чуть-чуть подумать, то можно понять, что переменную скор создавать нам нужно

316:12

Speaker C

всего лишь один раз. И get readyрейди писать тоже всего лишь один раз. Ну, давайте я это как бы уберу из тела цикла и до цикла напишу, потому что нам нужно сначала создать переменную скор, вывести getтреди, вывести счёт и потом уже

316:30

Speaker C

начать пролетать через трубы. То есть нам зациклить нужно только алгоритм пролетания через трубу. Нам не нужно зацикливать алгоритм приветственного сообщения и создания переменной счёта.

316:43

Speaker C

Нам один раз только нужно это всё сделать, а зациклить нужно именно пролёт через трубу. Ну давайте посмотрим, что получилось у нас в этот раз. Запускаю программу. Значит, GT readyди счёт ноль.

316:58

Speaker C

Вы подлетаете к трубе один, счёт один. Вы подлетаете к трубе один, счёт два. Ну, как мы можем заметить, хотя бы у нас счёт увеличивается каждый раз, когда мы пролетаем через трубу. Но что странно, мы постоянно пролетаем к одной и той же

317:13

Speaker C

трубе. К первой трубе здесь, к первой трубе здесь, к первой трубе здесь. А почему? Да потому что мы зациклили алгоритм, где мы выводим прямо строчку, где у нас эта единичка. Но мы бы хотели эту единичку каждый раз выводить разную,

317:27

Speaker C

в зависимости от того, какая у нас итерация. Если первая итерация, то выводить один. Если вторая итерация, то выводить два. Если третья итерация, то выводить три. Ну, у нас есть как раз для этого переменная, которая меняется на каждой итерации, которую мы можем

317:42

Speaker C

выводить. И она как раз-таки показывает то, какую, условно говоря, трубу мы пролетаем. Если у нас первая итерация и I = 1, тогда мы пролетаем первую трубу.

317:53

Speaker C

Если у нас вторая итерация, i = 2, мы пролетаем через вторую трубу. Ну давайте, сохраняю файл, запускаю программу.

318:01

Speaker C

видим, наши трубы теперь меняются. Мы сначала подлетаем к первой трубе, пролетаем через первую трубу, пролетели, счёт один. Потом мы подлетаем ко второй трубе, пролетели вторую трубу, счёт два.

318:16

Speaker C

Потом подлетаем к третьей трубе, мы её пролетаем, счёт три. Давайте даже для наглядности я перед каждой итерацией буду ещё выводить вот такие вот тире для того, чтобы разделять наши с вами итерации. И вот видим, что первая наша тире - это значит первая итерация.

318:38

Speaker C

Оп, вот вторая итерация. Вот третья итерация. И что самое интересное, теперь пролететь, к примеру, не через три, а через 10 труб мы можем всего лишь поменяв одну вот эту вот циферку. Одну циферку меняем, и у нас количество раз,

318:57

Speaker C

которое вот этот код будет выполняться, меняется с трёх раз до 10ти раз. И что самое ещё более удивительное, мы тут можем 1.000 написать, и у нас 1.000 раз будет пролёт через трубу. И, соответственно, 1.000 раз мы с вами

319:13

Speaker C

будем менять наш счёт, наберём 1.000 очков. Ну, давайте я запущу эту программу по приколу. Опа, она выполнилась. То есть на меня даже памяти терминала не хватило. То есть память терминала - это он помнит, сколько до этого было выведено символов. Не

319:26

Speaker C

хватило, чтобы всё это сохранить. Только самые последние трубы. Ну вот, как мы видим, у нас всё выполнилось, как мы и хотели. Мы подлетаем к трубе 943. Мы её пролетаем счёт 943. И в самом самом конце счёт 1.000. Это означает, что наш

319:43

Speaker C

код, который написан в теле цикла, произвёл 1.000 итераций. Для этого нам циклы и нужны, чтобы не копировать вот так вот код 1.000 раз, а просто один раз это в телецикла написать и менять просто одну циферку. То есть, допустим, если бы

320:02

Speaker C

у нас в игре Flopyбр были какие-нибудь уровни, в которых нужно нагенерировать, допустим, 15 труб. То есть, если ты 15 труп пролетел в этом уровне, то ты уровень прошёл, на следующем уровне у тебя уже будет 16 труб, то генерация

320:17

Speaker C

этих труб просто бы запихивалась в цикл. У нас бы было что-то типа начинаю генерировать уровень.

320:29

Speaker C

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

320:58

Speaker C

раза. трубы сгенерируем в нашем уровне. Ну и в конце опять же я напишу, что мы генерация уровня окончена.

321:12

Speaker C

Запускаю. Оп, начинаю генерировать уровень. Первая труба, вторая труба, третья труба. Генерация уровня окончена. А потом мы бы захотели сгенерировать уровень, в котором уже 10 труп. И нам, как разработчикам, осталось бы просто поменять вот эту вот циферку.

321:28

Speaker C

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

321:44

Speaker C

где у нас 10 труб. Каждую трубу мы даже можем подписывать. То есть тут уже ваша воля как разработчика. Можете вообще что угодно писать в этом телецикла. Оно как бы вас, ну, не ограничивает.

321:57

Speaker C

Единственное, что оно даёт - это несколько раз повторять то, что написано в коде. На каждой итерации переменная будет меняться на такое значение, которое вы тут вот укажете. И будет это всё выполняться до тех пор, пока выполняется это условие. Если на

322:13

Speaker C

очередной итерации вот это условие не выполнится, то цикл завершится. Ну, тут я подпишу, что труба, номер и тут вот i переменную запускаю.

322:26

Speaker C

Начинаю генерировать уровень. Труба номер один, труба номер два, труба номер 3, 4. Ну и так как у нас тут циферка 10, и мы от одного до 10 идём по одному, то есть 1 2 3 4, вот у нас 10 труп

322:39

Speaker C

изгенерировалось, и генерация уровня окончена. Всё, мы буквально с вами сейчас написали генератор уровней Flb, который у нас может конфигурироваться просто одной циферкой. То есть мы можем одну циферку менять, и в зависимости от этого у нас будет меняться уровень

322:55

Speaker C

целый. Вот я пятёрочку ставлю. Что у нас произошло? Ну, у нас всего пять труп сгенерировалось, типа довольно простой уровень. Можем тут 500 написать. Ну вот, серьёзно, так как этот цикл, он выполнит то, что мы от него хотим. 500 труб было

323:10

Speaker C

сгенерировано, генерация уровня окончена, и мы постепенно начинаем сталкиваться с ещё одним аспектом программирования. Именно самое настоящее программирование. не просто вывод на экран сверху вниз, а уже описание какого-то алгоритма. До этого мы с этим сталкивались, когда проходили условные ветвления. То есть мы начинаем выполнять

323:31

Speaker C

нашу программу не просто сверху вниз, а она начинает выписывать какие-то пируэты. Либо у нас ветвление происходит, либо зацикленность. Самые простые программы - это просто сверху вниз у нас идёт выполнение. Там первая команда, вторая команда, третья, четвёртая. Программа закончилась. А

323:47

Speaker C

настоящие программы - это когда у нас идёт выполнение, потом какое-то условное ветвление, потом продолжение, ещё одно ветвление. Из этого ветвления у нас может быть цикл начаться, потом дальше идёт выполнение линейное, потом опять какое-то условное ветвление, опять какой-то цикл пошёл, мы там что-то

324:04

Speaker C

нагенерировали, опять условное ветвление, то тут какие-то переменные создали. Вот это уже программирование, когда у нас нелинейное выполнение, когда у нас какой-то алгоритм. В данном случае у нас алгоритм, который 500 труб нам генерирует на нашем уровне. Мы, кстати, можем в этом теле использовать и

324:22

Speaker C

условные конструкции. Почему нет? Мы можем, допустим, каждую нашу чётную трубу, то есть каждую вторую трубу делать красной. Вот я тут скопировал символ красной трубы, и мы можем каждую вторую трубу делать красной. Как это сделать? То есть, по сути, нумерация

324:39

Speaker C

трубы, вот эти вот тире и пустая строка в конце, они должны остаться. Меняться должна только труба. Поэтому мы тут можем написать условие, если I 2 = 0, что это такое? Это проверка на чётность.

324:54

Speaker C

То есть процент - это, как мы помним, остаток отделения. И остаток отделения на два, если даёт ноль, значит, число чётное. Если остаток отделения на два не даёт ноль, значит, число нечётное. И мы хотим каждую чётную трубу делать красной. Ну а если у нас нечётная труба,

325:11

Speaker C

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

325:32

Speaker C

он наш самый алгоритм. Мы уже не просто сверху вниз выполняем программу. Мы мало того, что зацикливаемся, так ещё и в каждом цикле у нас происходит условное ветвление. Вот наше самое настоящее программирование, которое постигается только практикой. Навык практики просто

325:49

Speaker C

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

326:09

Speaker C

данном случае у нас на каждой итерации менялась переменная I. Вот она каждый раз менялась. Ну и если I была чётная, то у нас цвет трубы менялся. То есть у нас красно-зелёные трубы генерировались.

326:21

Speaker C

Циклфор в Голенге, повторюсь, можно использовать не только для того, чтобы перебрать переменную i, а для того, чтобы перебрать, например, какую-нибудь коллекцию. Но с коллекциями мы с вами пока ещё не знакомы. Ну давайте ещё для прикола тут вот пять труб сделаем. Не

326:37

Speaker C

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

326:51

Speaker C

Четыре - это опять у нас чётная, делится на два без остатка. Ну и пять зелёненькая труба.

326:57

Speaker C

Генерация уровня окончена. Вот такой уровень мы с вами сгенерировали. Есть ещё две вещи касаемо циклов, которые нам необходимо обсудить и которые нам необходимо рассмотреть. Первая вещь - это бесконечные циклы. Вторая вещь - это ключевое слово брейк, которое служит для

327:11

Speaker C

того, чтобы преждевременно циклы заканчивать. Перед тем, как мы рассмотрим две эти вещи, нам необходимо рассмотреть дополнительные ящики с инструментами. Первый из них называется мас/run. Второй называется time. Сейчас мы их по очереди рассмотрим. То есть мы с вами знаем, что у нас есть ящик с

327:29

Speaker C

инструментами FMT, благодаря которому мы можем выводить текст на экран. Вот я обращаюсь к этому ящику с инструментами.

327:36

Speaker C

Из него беру инструмент Printl и вывожу на экран текст, который захочу. В данном случае Hello World. Запускаю. И вот я благодаря инструменту Printn из ящика инструментов FMT вывел на экран строчку Hello World. О'кей. Давайте теперь подключим дополнительный ящик с

327:54

Speaker C

инструментами. Возьмём второй ящик с инструментами. Называется он Mass/round. Для того, чтобы взять несколько ящиков с инструментами, я тут поставлю открывающую круглую скобочку, потом поставлю закрывающую круглую скобочку. И между этими скобочками, помимо уже взятого ящика с инструментами FMT, я возьму второй ящик с

328:13

Speaker C

инструментами MAS/run. Таким образом, мы с вами взяли уже не только ящик с инструментами FMT, а два ящика с инструментами. Второе вот/run, такое у него название. Что мы можем делать с помощью этого пакета/run? Мы можем генерировать рандомные циферки. Как это выглядит?

328:33

Speaker C

Давайте я вторым выводом напишу рандомная цифра двоеточя. И здесь я после двоеточия воспользуюсь этим ящиком с инструментами RН. Поставлю точку и возьму из этого ящика с инструментами инструмент под названием int N. Вот он.

328:53

Speaker C

Что это такое? Мы в этот int n можем написать вот в эти круглые скобочки какую-нибудь циферку, например, пять. и он сгенерирует рандомное число от нуля, то есть ноль включительно до числа, которое мы туда напишем. Ну, это число не включительно. То есть, если мы пишем

329:12

Speaker C

rand n и передаём пятёрочку, то нам тут сгенерируется какое-нибудь одно рандомное число. Либо ноль, либо один, либо два, либо три, либо четыре. Всё. То есть пять не включительно от нуля до четырёх. Если тут ставим 10, то генерируется одно рандомное число от

329:29

Speaker C

нуля до 10, но 10 не включительно. То есть у нас будет от нуля до девяти. Вот так вот. О'кей, давайте выведем на экран. То есть вот я генерирую тут какое-то рандомное число от нуля до 10ти. 10 не включительно. Запускаю и

329:43

Speaker C

вижу рандомная цифра ноль. Потом ещё раз запускаю рандомная цифравом. Ещё раз запускаю рандомная цифра пять. То есть мы благодаря ящику с инструментами ма/rant можем брать инструмент под названием intN и благодаря этому инструменту генерировать какое-то рандомное число. При каждом запуске

330:02

Speaker C

программы это число будет разное, потому что оно рандомное. Хорошо. Таким образом мы познакомились с вот этим вот ящиком с инструментами/run. Поняли, что мы можем генерировать какие-то рандомные числа благодаря инструменту int, ну и выводить их, например, на экран. А также можем, в

330:19

Speaker C

принципе, эту генерацию чисел вставить в условия наши. То есть у нас есть условное ветвление, и я хочу смотреть, что если rand n у меня сгенерировал число один, тогда я выведу на экран. Я с генерировал рандомно число один. Ну,

330:42

Speaker C

иначе я не попал в единицу. Вот так вот. То есть вот здесь вот, что я написал rand n в скобочках 2. То есть у меня тут будет генерироваться какое-то рандомное число, либо ноль, либо один.

330:58

Speaker C

Ну то есть два не включительно, поэтому тут от нуля до двух два не включительно, либо ноль, либо один. И, соответственно, на запуск программы, в котором у меня тут сгенерируется единица, я выведу. Я сгенерировал рандомно число один. Где у

331:13

Speaker C

меня тут сгенерируется ноль? Я выведу. Я не попал в единицу. Давайте запустим. Я сгенерировал рандом на один.

331:21

Speaker C

Хорошо. Второй запуск. Мы уже не попали в единицу. Потом опять не попали. Опять не попали. Оп, попали в единицу. Таким образом, мы можем рандомно генерировать какие-то числа, выводить их на экран, либо в условиях генерировать какое-то рандомное число и сравнивать его. Для

331:38

Speaker C

чего мы вообще сейчас рассмотрели этот инструмент int N изками RAN? для того, чтобы в наших примерах уметь создавать видимость каких-то случайных событий. То есть мы благодаря тому, что генерируем какое-то случайное число и сравниваем его, например, с единичкой, мы можем

331:58

Speaker C

создавать события с какой-то определённой долею вероятности. То есть тут у нас генерируется от нуля до двух два не включительно, то есть либо ноль, либо один. И так как я сравниваю с единицей, то у меня шанс того, что выпадет эта единица 50%. Потому что 50%,

332:15

Speaker C

что выпадет ноль, 50% что выпадет единица. О'кей? А если бы я тут ставил rand n?

332:23

Speaker C

Тогда у меня бы уже в теории могло сгенерироваться 0 1 2 и 3. И я бы тогда, если бы тут сравнивал с единицей, тогда бы шанс того, что вот это вот условие даст истину, шанс того, что тут сгенерируется у меня всё-таки единица,

332:39

Speaker C

он уже 25%, потому что у меня четыре возможных варианта исхода, и мне нужен только лишь один, то есть 1/4 25%. Таким образом, повторюсь, благодаря вот этому рандомному генератору мы можем как бы имитировать какие-то случайные события в нашей программе. Это нам потребуется для

332:58

Speaker C

дальнейшего разбора вот этих вот двух тем, которые я обозначил. О'кей. Можем генерировать рандомные числа, выводить их на экран и ставить в условие. Хорошо.

333:08

Speaker C

Теперь давайте разберём ящик с инструментами. Для чего он нам нужен. Вот этот вот код я пока сотру и подключу ящик с инструментами. Возьму его. Ну, ман мы не используем, он нам не нужен, поэтому можно пока стереть. О'кей. То есть у нас есть ящик

333:25

Speaker C

с инструментами FMD, ящик с инструментами time. Давайте я покажу, что мы можем делать при помощи ящика с инструментами. Ну, для начала я хочу объявить самый обычный цикл. I = 1, I меньше либо равно 5, I + И каждой

333:41

Speaker C

итерации я буду выводить новое. [аплодисменты] итерация I и вот так вот значение переменной I. Теперь сохраняю, запускаю программу. Ну и вижу, у меня по сути вся программа выполнилась практически моментально, потому что итерация цикла - это очень быстрая операция для языка

334:02

Speaker C

программирования. И у нас вот моментально выполнилось 1 2 3 4 5. Ещё раз запускаем, выводится моментально. Но я теперь хочу, чтобы после каждого вывода на экран фразы "Новая итерация" у меня программа приостанавливала своё выполнение на сколько-то там миллисекунд

334:18

Speaker C

для того, чтобы я видел, что моя программа выполняется не моментально, а чтобы я видел последовательное выполнение своей программы. Ну то есть это мне нужно только для того, чтобы в терминале видеть результат не сразу весь, а по чуть-чуть. Для этого нужно

334:33

Speaker C

взять ящик с инструментами Time и воспользоваться из этого ящика с инструментами Time инструментом sleep.

334:41

Speaker C

Что этот инструмент делает? Он принимает какую-то продолжительность времени, на которую нужно остановить выполнение программы. Выполнение программы останавливается в той строчке, в которой этот time сleп написан. Давайте я тут напишу 500 миссекунд. Выглядит следующим образом.

334:59

Speaker C

Мы литерал умножаем на какую-то продолжительность времени, то есть умножаем 500 на миллисекунду, получаем 500 мскунд. Таким образом, у меня моя программа после каждого вывода фразы новая итерация будет засыпать на 500 мскунд. Таким образом, у меня вывод этих фраз будет разделён чисто визуально.

335:20

Speaker C

Давайте посмотрим. 1 2 3 4 5. Видим, у нас теперь программа выполняется не моментально, как до этого.

335:30

Speaker C

Оп. А, по чуть-чуть. То есть я могу видеть, что мои итерации немножечко разделяются. Ну, по сути, с точки зрения какой-то логики программы, это бесполезный таймсп. Он нам тут ничего не дал. Единственное, что нам тут этот таймсп даёт - это возможность увидеть

335:48

Speaker C

вывод фраз в цикле, разделённый немножечко во времени. Таким образом, мы посмотрели, что с помощью ящика с инструментами МА/rant мы можем генерировать какие-то рандомные цифры, рандомные числа, а при помощи ящика с инструментами Time мы можем останавливать выполнение нашей программы

336:06

Speaker C

в каком-то месте на заданный промежуток. То есть тут мы можем написать 500 time, что это значит? Что тут наша программа заблокируется на 500 часов. Ну, как бы я этого не хочу, поэтому оставлю 500 мскунд. Хорошо, рассмотрели ма/run, рассмотрели time. Теперь благодаря этим

336:27

Speaker C

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

336:47

Speaker C

имитацию игры Flppy Bird, но только чтобы мы могли бесконечно пролетать через эти трубы, прямо как в настоящей игре Flird, где игра заканчивается только тогда, когда игрок у нас врежется в какую-то трубу. Ну хорошо, давайте начнём это делать. То есть сначала

337:04

Speaker C

опишем какую-то одну трубу, один пролёт через трубу, потом запихнём это всё в цикл и посмотрим, как бы мы могли сделать так, чтобы игрок мог бесконечно пролетать через трубы до тех пор, пока он не врежется. Ну хорошо, мы бы сначала

337:19

Speaker C

написали get ready, типа приготовьтесь, и потом захотели бы вывести счёт изначально, то есть счёт изначально какой-то. Нам нужно создать, собственно, эту самую переменную скор, в которой мы будем хранить наш счёт. счёт, двоеточие и вывожу счёт. Изначально он у нас ноль.

337:35

Speaker C

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

337:50

Speaker C

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

338:16

Speaker C

успешно пролетел через трубу. Оп, наша птичка пролетела через трубу. Если птичка пролетела через трубу, тогда мы увеличиваем наш счёт на один. Ну, при помощи инкремента беру и увеличиваю счёт на один. И после каждого пролёта успешного трубы я хочу выводить наш

338:34

Speaker C

счёт. После этого пролёта заново вывожу счёт. И тут скор. Ну давайте запустим нашу программу. И видим ТРЕ счёт ноль. Я подлетаю к первой трубе, пролетаю через трубу. Успешно пролетел через трубу.

338:49

Speaker C

Счёт один. Ну хорошо. Теперь я хочу это всё как-то закольцевать. Ну то есть, чтобы у нас итеративно происходил пролёт через трубы. Не буду же я вот так вот копировать вот это вот всё.

339:00

Speaker C

несколько раз мы уже с вами умеем писать циклы. Давайте я напишу цикл. I у меня будет равно 1, I меньше либо равно пти.

339:10

Speaker C

То есть, допустим, у нас на уровне пока что всего пять труб. I++. И каждый раз у меня будет птичка подлетать к трубе. Но если я так оставлю, как сейчас есть, то будет странно, потому что постоянно будет выводиться на каждой итерации. Подлетаю

339:26

Speaker C

к первой трубе. Ну, у нас же как бы трубы-то постоянно разные. Сначала первая, потом вторая, потом третья. У нас постоянно подлетаю к первой трубе.

339:35

Speaker C

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

339:50

Speaker C

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

340:02

Speaker C

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

340:15

Speaker C

ГТРИ, счёт ноль. Подлетаю к трубе, пролетаю. Успешно пролетел. Счёт один, потом опять подлетаю к трубе, пролетаю, счёт два, ну и так далее. Ну о'кей, вроде всё круто, но есть проблема. Я хотел сделать бесконечный уровень, да, чтобы игрок мог летать до тех пор, пока

340:32

Speaker C

он не врежется, но в итоге сделал просто уровень из пяти труб. То есть в итоге пользователь, когда пролетает пятую трубу, то игра просто завершается. Я бы хотел сделать так, чтобы у нас вот этот пролёт через трубы был бесконечный до

340:46

Speaker C

тех пор, пока пользователь не врежется в трубу. Ну, для начала, для того, чтобы чисто визуально разделять вот эти вот выводы на каждой итерации, я воспользуюсь инструментом сп ящика с инструментами time. Для чего? Сейчас я запускаю нашу программу и вижу, что все

341:03

Speaker C

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

341:18

Speaker C

И точно так же на 500 мскунд будем засыпать. Теперь, если я запущу программу, то у меня каждая итерация будет во времени разделяться как раз-таки на вот эти вот самые 500 мскунд. Запускаю. Первая, вторая, третья, четвёртая, пятая. Оп. Отлично.

341:34

Speaker C

Теперь мы можем видеть, что наши пролёты через трубу выполняются не моментально, а постепенно. 1 2 3 4 5. Всё хорошо. Ещё раз повторюсь, что тут Time Sleep, он не несёт в себе какой-то логики конкретно для нашей игры. Он просто помогает нам,

341:52

Speaker C

как людям, которые смотрят в терминал, видеть, что программка у нас выполняется постепенно. Одна итерация за другой. Не сразу же все пять итераций в одну миллисекунду вывелись, а постепенно первая вторая третья четвёртая пятая и так далее. О'кей. Теперь возвращаемся

342:09

Speaker C

к нашему вопросу. Как же сделать бесконечный уровень? То есть мы поняли, что мы можем пролетать через трубы, мы можем с помощью цикла одну циферку поменять и тут сделать наш уровень гораздо длиннее, но тем не менее уровень всегда будет ограничен. 100 или 1.000

342:27

Speaker C

или миллиард мы тут поставим, всё равно уровень будет ограничен. Я же хочу сделать бесконечный уровень. Мне нужен для этого бесконечный цикл. Как в Гошке выглядят бесконечные циклы? Бесконечные циклы в Гошке очень похожи на то, что мы с вами уже использовали. Просто после

342:44

Speaker C

ключевого слова for не нужно ничего указывать. Стираем это и всё. Таким образом, мы с вами создали бесконечный цикл, потому что после ключевого слова for сразу же идёт тело цикла. Таким образом, мы не накладываем никакие условия на то, чтобы этот цикл у нас

343:03

Speaker C

когда-либо закончился. А значит, он никогда не закончится, будет выполняться бесконечно. Давайте запустим нашу программу и посмотрим вообще, как это всё выглядит. Запускаю программу. Счёт 1 2 3 4 5 6 7 8 9 и всё.

343:18

Speaker C

И наш пользователь полетел, пролетает через трубы. То есть у нас бесконечный цикл, как бы бесконечный цикл. Наша программа вот в этом бесконечном цикле бесконечно закольцевалась и всё. И она так и будет выполняться. Как же нам остановить эту программу? Нужно нам

343:33

Speaker C

поставить фокус на терминал, то есть не на редактор кода, а именно на терминал. И тут нажать Ctrl C. Всё, мы руками, так сказать, экстренно завершили нашу программу. Ну, потому что иначе она бы у нас никогда не завершилась, потому что у

343:47

Speaker C

нас бесконечный цикл. Таким образом, мы с вами узнали, что мы можем создавать бесконечные циклы. Просто нужно написать ключевое слово for и тело цикла. И это тело цикла будет выполняться бесконечно.

343:58

Speaker C

Для чего нам это нужно? Ну, например, вот наш рассматриваемый кейс, что мы хотим играть во Flapy Bir Bird не какое-то ограниченное количество раз, там 10, например, или 15, а я хочу играть во Flapy Bir Bird до тех пор,

344:11

Speaker C

пока я не врежусь. Но сама игра должна быть бесконечная, и завершаться она должна не за какое-то определённое количество итераций, а тогда, когда игрок врежется. Ну хорошо, мы с вами сделали бесконечный цикл, но никак не реализовали логику, где у нас игрок

344:27

Speaker C

всё-таки врезается. Давайте же это сделаем. Ну, так как у нас неполноценная игра Fl Bir, так как у нас всё-таки такая текстовая симуляция, то вот этот вот самый случайный момент, когда пользователь может врезаться в трубу, я буду имитировать благодаря ящику с

344:44

Speaker C

инструментами ма/run. Не зря мы его рассматривали. Как раз-таки благодаря вот этому генератору рандомных чисел я буду имитировать случайное событие, когда пользователь всё-таки врежется в трубу. Как это будет выглядеть? Я буду писать, если rand то intдам циферку 4 = 1. О'кей. Что я тут написал?

345:10

Speaker C

Я сказал, что вот этот вот блок кода выполнится с шансом 25%, потому что rand n генерирует 0, 1 2 либо 3. И если у нас сгенерируется единичка, тогда выполнится этот блок кода. Получается, что генерация единички у нас - это один шанс

345:30

Speaker C

из четырёх, то есть 1/4, а это 25%. То есть шансом 25% вот это выражение даст истину и выполнится вот этот вот код.

345:39

Speaker C

Хорошо, что я хочу делать шансом 25%. Шансом 25% я буду врезаться в трубу. Как это выглядит? Я буду выводить на экран.

345:49

Speaker C

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

346:07

Speaker C

врезалась. Ну хорошо. То есть с шансом 25% я буду врезаться в трубу и показывать на экране, что, мол, вот птичка врезалась в трубу. Давайте запустим нашу программу, посмотрим, что вообще будет. Так, успешно у Опа.

346:24

Speaker C

Я подлетаю к трубе, пролетаю через трубу, я врезался в трубу и дальше пошло выполнение нашего цикла. То есть мы хоть и написали вот эту вот логику, что с шансом 25% мы врезаемся в трубу, всё равно дальше продолжается наш

346:39

Speaker C

бесконечный цикл. Почему? Потому что мы во время того, когда мы врезались в трубу, мы этот цикл не прервали. Как нам прервать цикл? при помощи ключевого слова breakй мы, если напишем breakй, то в момент, когда наша программа достигнет этого ключевого слова брейк, то она

347:01

Speaker C

прервёт цикл, в рамках которого этот самый брейк написан. То есть мы можем даже вот нажать на это ключевое слово брейк, и нам редактор кода сразу же подсветит цикл for, который будет прерван этим самым брейком. Ну давайте теперь запустим нашу программу.

347:17

Speaker C

Запускаю. Опа. У нас так получилось, что рандом сыграл сразу же на первой трубе, и мы врезались в самую первую трубу. Треди счёт ноль. Я подлетаю к трубе, пролетаю через трубу, врезался. Всё. То есть нам рандом как бы не благоволил. Мы

347:35

Speaker C

врезались на первой же итерации. На первой же итерации нам тут выпала единичка. Условие дало истину, и мы завершили наш цикл при помощи ключевого слова брейк. О'кей. Давайте ещё раз попробуем запустить. Первая, вторая, третья, четвёртая. Опа, на пятой трубе

347:51

Speaker C

врезались. Ну, я хочу, давайте в конце выводить итоговый счёт нашей игры. То есть, если мы с вами вылезли из этого цикла, если у нас бесконечный цикл прервался и мы продолжили своё выполнение, это значит, мы где-то в этом бесконечном цикле, где-то в нашем

348:06

Speaker C

бесконечном уровне игры Flppy Bird всё-таки врезались, и у нас отработала конструкция Break. Значит, тут я могу вывести game over, то есть игра окончена, и ваш итого счёт и выведу нашу переменную скоe. Давайте посмотрим, как это выглядит. Запускаю первое. Опа,

348:28

Speaker C

первую трубу пролетел. Подлетаю к трубе второй. Пролетаю через вторую трубу, но не пролетел. Врезался во вторую. О'кей.

348:35

Speaker C

Ещё запускаем. Первая, вторая, третья, четвёртая. А на пятое опять врезался. Можем, в принципе, сделать шанс врезания в трубу меньше и посмотреть, что мы будем тогда пролетать в среднем дальше.

348:47

Speaker C

Для того, чтобы сделать шанс врезания в трубу меньше, я просто увеличу число, которое может сгенерироваться у нас здесь. Ну, поставлю здесь, например, восьмёрку. Что это значит? Что тут может генерироваться любое число от нуля до восьми не включительно, то есть 0 1 2 3

349:04

Speaker C

4 5 6 и 7. И получается, я буду врезаться в трубу только если сгенерировалось именно один. А тут один у нас генерируется с шансом один из восьми. То есть 1/8, это, если я ничего не путаю, 12,5%. То есть не 25%, как у

349:21

Speaker C

нас до этого было, а 12,5. Ну давайте запустим опять нашу программу. Первая, вторая, третья, четвёртая. Четвёртые врезались, то есть пролетели только три трубы. Итоговый счёт три. Ну давайте ещё раз. 1 2 3 4 5 6 7 8 9 10 11 12 Ну прямо

349:40

Speaker C

полетели вообще. Вон 15 труп пролетели, в шестнадцатую врезались, всё Gameover. Ваш итоговый счёт такой-то. О'кей. Ну, по сути, мы с вами рассмотрели всё, что хотели. Это бесконечные циклы. Что мы, если в цикле не ставим тут никаких условий, просто пишем ключевое слово for

349:57

Speaker C

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

350:11

Speaker C

При помощи ключевого слова брейк мы можем завершать и не бесконечные циклы. Давайте я вот это вот всё сотру и покажу самый простой вот наш цикл. То есть for i = 1, I меньше либо равно 5, i +. Ну и

350:25

Speaker C

тут буду выводить на экран итерация. И тут переменную i запускаю. 1 2 3 4 5. Хорошо, от одного до пяти все итерации прошли, но я тут могу добавить такую искусственную проверку, что если i = 3, тогда breakйк. То есть, ну, просто

350:43

Speaker C

буду досрочно завершать наш цикл, когда i станет равно тём. Оп, 1 2 3. И i стало равно 3. Я завершил цикл благодаря ключевому слову брейк. То есть благодаря ключевому слову брейк мы можем завершать наши циклы в любой момент, когда

350:58

Speaker C

захотим. Ну, обычно просто брейк не пишется, потому что тогда завершится цикл на первой же итерации. Обычно брейк у нас пишется в рамках каких-то условий.

351:08

Speaker C

То есть у нас выполняется какой-то цикл, как у нас с вами до этого было, что у нас выполняется бесконечный цикл пролёта через трубы. И в какой-то момент, когда пользователь у нас врезается в трубу, тогда мы этот бесконечный цикл нашей

351:21

Speaker C

бесконечной игры Flappy Bird прерываем и выводим итоговый счёт. Ну всё, поздравляю. Мы с вами изучили. Мало того, что бесконечные циклы и ключевое слово брейк, так ещё и разобрали два дополнительных ящика с инструментами.

351:35

Speaker C

Первый - это ма/run, благодаря которому мы можем генерировать рандомные цифры, рандомные числа. А второй - это timeйм, благодаря которому мы можем останавливать выполнение нашей программы в любом месте на любой промежуток времени, который захотим. Иногда этот тайм слип бывает удобен, чтобы при

351:53

Speaker C

выводе на экран более красиво различать наши итерации. То есть вот когда у нас есть тайм слип, у нас отдельно выводится первая вторая третья четвёртая пятая, шестая, да, вот 1 2 3. И довольно красиво. Если бы у нас не было

352:06

Speaker C

таймслипа, то наша бы программа тоже отрабатывала практически моментально, потому что тот код, который у нас написан, он для языка программирования, он для современных процессоров является просто легчайшим алгоритмом, который выполняется за долю секунды. Оп, видите, мы пролетели, ну, типа 16 труб просто за

352:25

Speaker C

долю секунды. Ну, и не совсем как-то понятно, что происходит. Вот мы просто моментально пролетаем семь труб. Хочется всё-таки выводы разделять, поэтому просто time сleп я пишу в конце каждой итерации. Можно вот одну секунду спать. Вот 1 умножить на секунду. То

352:41

Speaker C

есть 1 секунда. Запускаю. Первая, вторая, третья, четвёртая, пятая. И вот пять труб пролетели и завершились. Это была наша первая, так сказать, ходка на цикл for. Первый наш подход к нему, первая попытка его осознать.

353:01

Speaker C

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

353:10

Speaker C

Поэтому чем раньше вы набьёте руку на решении задач с этими примитивами языка программирования тем [музыка] лучше. Следующая наша тема - это функции. Мы посмотрим вообще, что такое функции, для чего они нужны и как используются. Сразу же перейдём к коду,

353:30

Speaker C

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

353:45

Speaker C

выполнение программы. Отсюда оно начинается. То есть мы тут можем написать что-нибудь, там Hello World. Сохраняю, запускаю. Ну и этот Hello World у нас вводится на экран. То есть с шестой строчки у нас программа начинает своё выполнение с главной функции main. Можем

354:03

Speaker C

ли мы создавать ещё какие-то функции? Можем, но почему нет? Допустим, у нас есть функция какая-нибудь hello. Создали ещё одну функцию. Ну, только он нам подчёркивает, что функция Hello ещё никогда нигде не используется. То есть unused не используется. Но создать-то

354:19

Speaker C

можем. Можем. Будет ли она какой-то эффект оказывать на программу? Нет, потому что у нас есть главная функция, главный кусок кода. Программа здесь начинается с её выполнение, здесь заканчивает. Но что же мы тогда тут написали и как вообще нам создавать,

354:35

Speaker C

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

354:55

Speaker C

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

355:13

Speaker C

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

355:34

Speaker C

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

355:50

Speaker C

Тут я напишу до вызова функции, потом после вызова функции, а тут я напишу Hello. В самой Hello Hello 1 и Hello 2. А давайте сразу программу запустим и посмотрим, что вообще тут будет происходить.

356:18

Speaker C

Всё, что мы написали, вывелось на экран до вызова функции. О'кей. А потом Hello 1 сразу, потом Hello 2, потом после вызова функции. А так что же тут вообще произошло? Давайте я сейчас на рисунке объясню ход выполнения программы благодаря написанному коду. Я сделал

356:40

Speaker C

скриншот написанного кода и вывода. Давайте посмотрим вообще по шагам, разберём, что тут происходит, почему мы получили именно вот такой вот вывод. Ну, наша функция main. Мы знаем, что функция main - это вот этот вот главный кусок кода, который начинается сразу же, как

356:55

Speaker C

только мы программу запускаем. Так как это называется main, то именно вот отсюда вот программа начнёт своё выполнение. Ну, собственно, мы начинаем идти. У нас девятая строчка, у нас вывод вот этого текста. Вот он у нас тут и вывелся до вызова функции. Потом мы

357:13

Speaker C

прописываем название другой функции. Как это вообще понимать? Что это вообще значит? Когда мы прописываем в какой-то функции название другой функции, вот тут вот мы прописали название hello, то мы тем самым передаём управление кода из нашей главной функции в другую функцию, которую мы с вами

357:37

Speaker C

вызвали. то есть. Мы тут вызываем функцию hello. Это значит, что в десятой строчке мы передаём управление функции Hello, и у нас дальнейшее выполнение кода будет осуществляться внутри этой функции. То есть мы сначала вывели вот этот вот до вызова функции. Вот мы его

357:57

Speaker C

тут вот вывели, потом вызвали функцию hello. Что это значит? что мы отдали управление программой функцией Hello. И дальше наша программа будет выполняться согласно функции Hello. Функция Hello - это тоже какой-то кусок кода. Вот он наш кусок кода, который ограничен

358:15

Speaker C

открывающими и закрывающими скобочками. И всё, что находится внутри этого куска кода - это тело функции. Вот это тело функции. Соответственно, когда мы с вами вызываем какую-то функцию и передаём управление программой этой функции, мы начинаем выполнять тело этой функции.

358:34

Speaker C

Что это значит? Мы вот вывели до вызова функции, вот оно вывелось, потом вызвали функцию hello, то есть передали ей управление. Это значит, что у нас дальше будет выполняться тело функции Hellow. А в теле функции Hello у нас вывод на

358:50

Speaker C

экран Hello 1 и Hello 2. Потом, когда функция, которой мы передали выполнение, завершается, доходит до завершения, то управление передаётся обратно в главную функцию. И у нас выполняется последний вывод. После вызова функции, то есть наш код сначала запускается функции main,

359:11

Speaker C

потому что, повторюсь, функция main - это самая главная наша функция, откуда вообще программа начинает своё выполнение. Отсюда начинаем своё выполнение. Переходим к девятой строчке.

359:21

Speaker C

У нас тут обычный вывод до вызова функции. Ну вот мы его как бы и выводим.

359:25

Speaker C

Потом наша программа вызывает функцию Hello, то есть мы передаём управление функции Hello. Соответственно, тут в десятой строчке у нас будет передано управление функцией Hello и будет выполняться её уже тело. Ну, соответственно, в её теле у нас Hello 1,

359:44

Speaker C

Hello 2. Вот мы видим эти выводы. Hello 1, Hello 2. И потом, когда функция подошла к своему концу, то она возвращает управление обратно в главную функцию. И мы продолжаем идти дальше.

359:55

Speaker C

Дальше у нас вывод после вызова функции. Соответственно, когда мы с вами вызываем какую-то функцию, это можно представить как будто бы мы на это место кладём код, который написан внутри этой функции, да? То есть, по сути, вот так вот мы можем удалить эту функцию hello,

360:15

Speaker C

запустить, и у нас будет то же самое. Но мы вывод Hello 1 и Hello 2 выносим из главной функции main в другую функцию, которую называем hello. Назвать мы её можем как угодно. Я отсюда это вырежу, вставлю и заместо вызова принтанов прямо

360:34

Speaker C

функции main я их вынесу в функцию hello, а потом просто вызову эту функцию hello. И по сути мы сделали то же самое, то есть мы просто вынесли кусок кода, вот этот Hello 1, Hello 2, назвали его Hello, и потом мы можем вызывать, мы

360:49

Speaker C

можем несколько раз вызвать функцию, например, давайте три раза её вызовем. Запустим программу. И у нас до вызова функции Hello 1, Hello 2, Hello 1, Hello 2, Hello 1, Hello 2 после вызова функции. Почему так? Да потому что мы в

361:03

Speaker C

девятой строчке вывели до вызова функции, потом в десятой строчке переходим к выполнению функции, вызываем её, передаём управление. Выполнили написанные тут команды, вернулись обратно в одиннадцатую строчку. А в одиннадцатой строчке мы опять передаём управление функции Hello. Опять выполняется её тело. Второй раз

361:22

Speaker C

выводится Hello 1, Hello 2. Опять, когда она завершается, управление возвращается в главную функцию, в двенадцатую строчку. А тут опять вызов Hello, опять передаётся управление функции Hello, опять выводится Hello 1, Hello 2, потом функция Hello завершается в выполнение, передаёт управление главной функции, и

361:39

Speaker C

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

361:53

Speaker C

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

362:07

Speaker C

понять, как функции работают. То есть первое, что мы можем понять, что функция - это просто какой-то кусок кода, у которого есть начало и есть конец, в рамках которого что-то происходит. У этого куска есть название, и мы можем вызывать команды, которые написаны в

362:23

Speaker C

этом куске кода, просто написав его название и поставив скобочки. То есть, что бы мы тут не написали, допустим, у нас тут будет написано: "Я [аплодисменты] функция". Меня вызвали я завершаюсь. И в конце ещё в этой функции будет опять же пустая строчка. Сохраняю,

362:52

Speaker C

запускаю до вызова функции. И поехали. Вызываем. Ну и я думаю, вы уже поняли. Выводится то, что написано в функции.

363:00

Speaker C

Выполняется код, который был описан в функции. То есть каждый раз, когда мы пишем название функции, мы просто её вызываем и просим выполнить кусок кода, который под этой функцией скрывается.

363:14

Speaker C

Поэтому каждый раз, когда мы прописываем с вами hello, когда мы прописываем название функции, у нас вызывается эта самая функция. И поэтому у нас каждый раз, когда мы прописываем hello, выводится на экран то, что заключено в теле этой функции. Первый раз вызвали

363:31

Speaker C

hello, второй раз вызвали hello, третий раз вызвали hello. Каждый раз мы передаём управление функции, которую мы вызываем. Я думаю, этот момент примерно стал понятен. Советую вам опять же попробовать это всё руками пописать. Нам никто не мешает создать ещё одну

363:48

Speaker C

функцию, которую мы назовём вообще как угодно. Мы можем назвать эту функцию абоба, и всё, что в ней будет происходить - это создаваться переменная а, которая равна, создаваться переменная B, которая равна 10, создаваться переменная C, которая равна 3. И мы

364:03

Speaker C

будем выводить на экран их сумму. Просто сумма a + b + c. Вот таким образом мы можем сразу же выводить результат какого-то выражения. И вот тут вот в конце вывести абобабобабо. То есть вызовем её. И после всей вот этой вот

364:18

Speaker C

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

364:27

Speaker C

То есть у нас будет 0 + 10 + 3. Ну давайте тут один поставлю. 1 + 10 + 3 - это 14, и выведется сумма 14. Запускаем.

364:37

Speaker C

Ну и вот опять же у нас после вызова функции, но после того, как мы написали вот этот вот вывод, у нас ещё вызвалась функция Боба. передалось ей управление, вызвался вот этот кусок кода, который называется абоба. И тут произошла

364:50

Speaker C

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

365:07

Speaker C

если мы в мейне создадим переменную, ну, допустим, у нас тут будет скор равно 5, и мы выведем его на экран. И даже несмотря на то, что у нас функции main создана переменная score, и мы её даже можем выводить на экран. Давайте я

365:21

Speaker C

запущу программу. Вот счёт пять у нас в самом начале. Эта переменная, она будет доступна только в том куске кода, в котором она создана. То есть, если переменная создана в куске кода main, значит, она будет доступна только в куске кода main. В куске кода Hello у

365:40

Speaker C

нас уже не будет никакой переменной скор, и мы не сможем к ней получить доступ.

365:45

Speaker C

Ну вот тут вот я, допустим, захочу вывести ещё. Подчёркивает score undefined. Тоже самое. Эта переменная score, она существует только в рамках функции main. В рамках функции Hello уже переменный ср не существует, потому что это другая функция, это другой кусок

366:03

Speaker C

кода, это другая область видимости. Соответственно, переменные, которые мы создаём в функции абоба, и C, доступны только внутри этой самой функции ABба.

366:14

Speaker C

они уже недоступны ни в какой другой функции. То есть функции main, если мы захотим вызвать а, вывести, да, просто на экран, мы не сможем тоже undefined.

366:23

Speaker C

A, хотя мы, казалось бы, определили эту переменную, но мы создали её в куске кода абоobба, функция абоobба. Поэтому мы с вами её можем использовать только в рамках этой функции, только в рамках этой области видимости. Я надеюсь, сейчас становится понятно примерно, что

366:41

Speaker C

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

367:03

Speaker C

пока что смотрим просто на то, как именно функции работают. Пока мы поняли, что мы можем создать какую-то функцию отдельную какую-то, написать в ней логику, а потом эту функцию вызвать, тем самым передав управление этой функцией и тем самым выполнив логику, которая

367:20

Speaker C

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

367:34

Speaker C

Также функции, помимо того, чтобы просто быть какими-то заготовленными кусками кода, могут принимать различные аргументы. Что это вообще значит?

367:44

Speaker C

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

367:50

Speaker C

Square - это с английского квадрат. И вот тут такая странная запись. Что-то там X in в скобочках. Что это вообще значит? Функции могут принимать аргументы. Мы, когда вызываем функцию, можем передавать в неё какую-то переменную. Как это выглядит? Давайте

368:09

Speaker C

пока будем просто выводить эту переменную на экран. Мы приняли в функции переменную X и выведу этот самый X.

368:21

Speaker C

сотру всё, что в мейне, и вызову square. И, как вы видите, мы только ставим скобочки, нам сразу же редактор кода подсказывает, что какую-то нужно передать переменную какое-то значение в функцию. То есть он просит, чтобы мы передали какой-то там x целочисленного

368:39

Speaker C

типа. Ну, мы можем написать, например, 5. Ну, давайте сохраним нашу программу и запустим её. Что мы видим? мы приняли функцию переменную x 5, то есть мы, когда вызываем какую-то функцию, мы можем не просто её вызывать как заготовленный кусок кода, а можем в неё

368:59

Speaker C

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

369:15

Speaker C

x в квадра. Ну и тут вот просто x. Сохраняю и запускаю нашу программу. Мы приняли функции переменную x² 25. То есть мы теперь можем использовать эту функцию квадрата и передавать в неё вообще любые значения, которые захотим. Несколько раз это

369:37

Speaker C

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

369:52

Speaker C

программе, когда захотим посчитать квадрат какой-то переменной, можем вызвать функцию square, передать в неё любое число. Это самое число в момент вызова функции встанет на место вот этой переменной, и функция выполнится с переменной x, значением которой будет то число, которое мы передали. Ну вот

370:13

Speaker C

смотрите, у нас три раза вызывается square. Первый раз со значением пять, потом со значением 10, потом со значением три. Ну и, соответственно, давайте сохраним файл и запустим нашу программу. Первый раз мы передали пять.

370:24

Speaker C

То есть мы зашли в функцию main, сразу же вызвалась функция square, и мы пошли в функцию square. У нас передалось пять.

370:32

Speaker C

То есть в момент, когда функция square начинает своё выполнение, в переменной x лежит 5. Ну и так как тут написано, что x должен быть типа in, мы не можем сюда передать ни строку, ни дробное число, потому что мы ждём именно integer,

370:49

Speaker C

именно целое число. Вот int - это сокращённое от integer, то есть целое число. Когда мы будем пытаться передать дробь, нам редактор кода скажет, что мы не можем использовать дробное число как целое, потому что мы ждём в функции square именно целое число, и передавать

371:07

Speaker C

мы туда можем только целое число. Ну давайте посмотрим, что вообще у нас за вывод получился. То есть мы вызываем первый раз сQР, передаём пятёрку. На место x становится пятёрка. Ну и у нас выводится, мы приняли функции переменную x, она равна пти, ну и x² 25. То есть

371:23

Speaker C

просто x, вывели это на экран. Дальше мы приняли функцию переменную x 10. Это уже когда мы второй раз с вами вызвали эту функцию. Она у нас вызвалась тот же самый кусок кода, но уже на место x встало число 10. Ну и мы вывели 10. 10²

371:39

Speaker C

100. То же самое с тройкой. Для большей наглядности мы можем писать ещё в мейне выводы на экран, чтобы видеть вообще поток исполнения программы.

371:52

Speaker C

Вызываю square от пяти и тут закончил выполнение square от пти. Ну и ещё выведу пустую строчку, чтобы разделять наши вызовы. Ну и, соответственно, скопирую вот это всё и вставлю, чтобы просто несколько раз не писать. Тут 10, тут у нас

372:18

Speaker C

три, тут опять же 10 и тут опять же три. Сохраняю, запускаю. И вот мы видим, что мы попадаем в функцию main. Опять же, почему выполнение начинается именно с функции main? Ведь у нас тут куча других разных функций, потому что эта функция

372:37

Speaker C

называется main. И разработчики языка программирования сделали так, что если функция называется main в пакете MIN, тогда она автоматически вызывается вместе с запуском программы. Поэтому программа начинает своё выполнение именно вот отсюда, то есть с первой самой строчки функции main. Ну и

372:59

Speaker C

поехали. У нас вызывается наша программа запускается, вызывается функция main автоматически. И тут нам выводится вызываю square от пяти. Потом, собственно, сам вызов функции. И когда мы вызываем функцию, мы видим по нашему выводу, что управление передаётся в функцию square. Здесь мы сразу же

373:19

Speaker C

выводим, что мы приняли функции переменную x, она равна пти. Вот здесь вот эта x = 5, потому что мы передали эту пятёрку как аргумент. Ну и вывели 5² 25. После этого наша функция square закончила своё выполнение и вернула

373:37

Speaker C

управление в вызывающую функцию. А вызывающая функция была main. То есть вызывающая функция - это та функция, из которой мы вызываем другую. В данном случае мы шли, пришли в square, прыгнули в square, выполнили его логику, и когда сэрare закончился, мы вернули своё

373:58

Speaker C

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

374:17

Speaker C

и потом управление возвращается обратно в функцию main. То есть наши функции, которые мы с вами описываем, они могут быть не просто кусками кода, которые выполняют какую-то вынесенную в отдельную часть логику, они ещё и могут принимать разные переменные. Для чего

374:34

Speaker C

это нам может быть нужно? Ну, теперь мы уже можем начать писать несколько более осмысленные функции. Допустим, мы с вами работаем официантами в ресторане. Я вот напишу допустим мы работаем официантами в ресторане. И у нас задача И у нас

374:56

Speaker C

задача. Для каждого нового гостя нужно накрыть ему стол, поприветствовать по имени и принять заказ и принести блюдо.

375:20

Speaker C

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

375:41

Speaker C

это накрываем на стол. Накрываю на стол. Потом нам нужно поприветствовать какого-то человека по имени. То есть привет, запятая, а имя нам откуда взять?

375:57

Speaker C

Непонятно. То есть, если бы мы, например, в мейни это всё писали, мы бы знали, что у нас вот есть Накрываю на стол. Привет, там, допустим, Иван.

376:09

Speaker C

[аплодисменты] Потом я принял заказ, и я принёс блюдо. Хорошо. А теперь, допустим, к нам после Ивана пришёл ещё Олег. Ну хорошо, мы это всё копируем. Привет, Олег.

376:28

Speaker C

Ля-ля-ля. Потом пришёл ещё Василий. Привет, Василий. Как мы видим, у нас вот эти куски кода, они абсолютно одинаковые. Давайте я сохраню, запущу программу.

376:42

Speaker C

Накрываю на стол. Привет, Иван. Я принял заказ, принёс блюдо. Ну давайте опять же добавлю вот эту вот пустую строчку, чтобы у нас разделялись эти выводы. Они были вот таким вот сплошником. Добавляю пустую строчку. Накрываю на стол. Привет, Иван.

376:59

Speaker C

Я принял заказ, принёс блюдо. Накрываю на стол. Привет, Олег. Принял заказ, принёс блюдо. Василий, ля-ля-ля, принёс блюдо. можем заметить, что наши вот эти вот куски кода, они отличаются одним единственным именем. То есть только меняется имя. И нам бы хорошо вот это

377:13

Speaker C

всё вынести в отдельную функцию, чтобы мы так же, как вот функцию hello мы вызывали. Мы бы могли вызывать вот эти куски кода просто, которые лежали бы в функции, но у нас загвоздка, у нас меняется имя, и мы можем это самое имя

377:31

Speaker C

передавать как аргумент функции, благодаря чему мы сможем использовать все эти выводы, но менять только имя.

377:40

Speaker C

Давайте я покажу, как бы это выглядело. Вот наша функция. Давайте её заново начну писать. Официант work.

377:49

Speaker C

Как мы уже договорились, она будет принимать имя. Имя у нас в строке, то есть это тип-страка, поэтому пишем сначала название переменной, которое мы принимаем, потом её тип. Тип писать обязательно, потому что у нас статическая типизация, чтобы наш язык

378:03

Speaker C

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

378:19

Speaker C

алгоритм, например, для Ивана, вставить его функцию и заместо Иван мы бы тут просто передавали нашу переменную name. Ну и потом можно ещё восклицательный знак добавить.

378:32

Speaker C

Соответственно, мы с вами вот эту вот логику, которая у нас вот тут вот повторяется постоянно, мы её взяли и вынесли в отдельную функцию. Что это нам позволит сделать? Мы теперь заместо вот этого длинного непонятного вывода в мейне можем три раза вызвать функцию

378:48

Speaker C

efficient work. Сначала для Ивана, потом для Олега и потом для Василия. Василий, это всё можем стереть и запустить нашу программу.

379:04

Speaker C

Накрываю на стол. Привет, Иван. Ля-ля-ля. Накрываю на стол. Привет, Олег. Ля-ля-ля. Накрываю на стол.

379:11

Speaker C

Привет, Василий. Ля-ля-ля. Как мы видим, мы упростили наш код с бесконечного повторения вот этих вот выводов до описания одной функции и вызова этой функции с разными аргументами. Сначала мы передали Иван и поприветствовали Ивана, накрыли ему на стол, потом

379:29

Speaker C

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

379:51

Speaker C

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

380:08

Speaker C

вместо вот этого вот непонятного чуда очень красивый лаконичный код, который состоит просто из трёх строчек.

380:17

Speaker C

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

380:33

Speaker C

них нет. И, соответственно, при вызове этих функций тоже нам не нужно было передавать никакие аргументы, потому что они никаких аргументов не принимают.

380:41

Speaker C

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

380:58

Speaker C

этими строчками кода, на самом деле, скрывается функция, в которую мы вынесли нашу работу. И, соответственно, тут уже на примере с работы официанта мы можем понять, в чём вообще смысл функции. В том, чтобы обобщить какой-то кусок кода, который выполняет одно и то же, но

381:16

Speaker C

чем-то вот отличается. В данном случае вот у нас всё одно и то же, но отличается только имя человека, которого мы приветствуем. Соответственно, мы вот этот весь алгоритм можем вынести в отдельную функцию и задать ей аргументом имя, типа строка, и всё. И мы можем

381:32

Speaker C

использовать эту функцию, просто передавая в неё разные имена. И нам не нужно каждый раз прописывать вот это всё тело функции. Функция-то может быть ещё больше. Функция вполне может быть и 100 строк кода, и 200. Смотрите, у нас вся

381:45

Speaker C

программа 51 строка кода, а бывают функции по 100 строк, по 150, по 200 строк кода. И поэтому каждый раз такие повторяшки писать в коде, это было бы просто преступлением, потому что тогда, допустим, допустим, мы бы использовали всё, как раньше. Вот это вот я давайте

382:04

Speaker C

закомментирую. Hello, Satru. Ну и тут вот как раньше мы бы использовали Иван, тут вот Олег и тут вот Василий. Ну, сохраняем, запускаем. Ну, вроде всё работает. Привет, Иван.

382:21

Speaker C

Привет, Олег. Привет, Василий. И у нас было бы таких пять приветствий. А теперь представим, что к нам бы после этого пришёл наш начальник и сказал, что, вообще-то, теперь нужно говорить: "Не: "Привет, Олег", а приветствую вас, господин Олег. Итак,

382:36

Speaker C

всем именам нужно говорить. Соответственно, что это значит? Это нужно, что нам теперь каждый раз, где мы написали вот эту вот логику, везде менять приветствие. Теперь нужно приветствую, господин Иван. Теперь приветствую, господин Олег. Теперь приветствую, господин Василий. Тут вот, допустим,

383:04

Speaker C

какой-нибудь у нас был бы Игорь. Ну, а тут Сергей. Привет, ствую, господин Игорь. Приветствую, господин Сергей. То есть мы этот код вместо того, чтобы где-то его один раз поправить, мы пять раз исправляем одно и то же, потому что это

383:27

Speaker C

у нас не вынесено ни в какую функцию, просто вот наложено вот прямиком вот так вот сверху вниз. А теперь представим, что к нам опять приходит начальник и говорит, что теперь каждому гостю, ещё перед тем, как его поприветствовать, нужно сказать, что мы для него от

383:43

Speaker C

заведения приготовили подарок. А опять нужно всё менять 10.000 раз. Мы вам подготовили подарок от [музыка] заведения. Опять это мы для Ивана поменяли, а теперь давайте для LEGO менять. Мы вам подготовили подарок от заведения. А теперь нужно, Василь, я

384:08

Speaker C

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

384:26

Speaker C

пять, а 50. И у нас в пятидесяти разных местах в нашей программе используется вот этот вот код. Что это значит? Что при малейших исправлениях нам нужно было бы менять код в пятидесяти местах. Это неудобно, это глупо, это ведёт за собой

384:43

Speaker C

ошибки, что где-то вы могли поменять, как нужно, а где-то забыть или допустить ошибку. И в итоге Сергею бы какую-то непонятную фигню мы сказали. Мы подготовили подарок отзывень. Что? А тут на самом деле ошибка. И вот, чтобы этого всего избежать, чтобы менять код всего

385:01

Speaker C

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

385:15

Speaker C

стол. Мы вам подготовили подарок от заведения. Приветствую, господин какой-нибудь. Смотря какое имя мы передадим. Я принял заказ. Я принёс блюдо. И теперь мы можем не писать это всё тысячу раз.

385:26

Speaker C

[аплодисменты] А просто вызвать функцию. И в чём тут преимущество-то? По сравнению с тем, что мы писали много-много раз одно и то же.

385:35

Speaker C

Представьте, что вот у нас вот тут вот пять вызовов этих работ официанта. Тут Василий, тут Игорь и тут Сергей. Хорошо. Вот мы всё вызываем.

385:44

Speaker C

Теперь к нам приходит начальник и говорит: "А вот после того, как ты принёс блюдо, теперь ещё у каждого гостя спрашивай, не хотите ли вы заказать что-нибудь ещё. И теперь нам вместо того, чтобы 50 раз это всё менять, нам

385:58

Speaker C

нужно один раз это поменять в функции. Не хотите ли вы заказать что-нибудь ещё? И теперь везде, где мы вызываем эту работу официанта, везде добавится вот это вот исправление. И нам не нужно это менять в пятидесяти разных местах. Ну вот давайте запущу программу.

386:22

Speaker C

Вот везде у нас добавилось вот это вот. Не хотите ли вы заказать что-нибудь ещё?

386:26

Speaker C

А теперь к нам приходит опять наш начальник, говорит, что в конце ещё скажите хорошего дня. И нам опять же теперь не нужно во всех местах это менять. Один раз функции поменяли и всё. И теперь мы запускаем и видим, что везде добавилось это желание

386:46

Speaker C

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

387:08

Speaker C

что каждый раз, когда у нас вызывается работа официанта, у нас вызывается вот этот вот кусок кода. А значит, если мы этот кусок кода поменяем один раз, он поменяется везде, где мы его вызываем.

387:19

Speaker C

Наши функции также могут принимать не только один аргумент какого-то определённого типа, могут принимать несколько аргументов разных типов. Могут принимать несколько аргументов одного типа тут уже как вы захотите. Допустим, у нас есть функция сум. Ну, она будет принимать а целочисленное, b

387:36

Speaker C

целочисленное и приветствие. То есть с английского гритинг - это приветствие строчного типа. Что она будет делать?

387:43

Speaker C

Она будет сохранять переменную S сумму A + B, потом выводить на экран приветствие, а потом выводить на экран результат суммы A + B. То есть сумма а + B равно И тут вот я вывожу эту нашу переменную, в которой мы сохранили

388:03

Speaker C

сумму. Ну давайте теперь вызовем эту функцию сум и передадим в неё. Опять же нам редактор кода подсказывает, что именно мы должны туда передать. То есть сум первым аргументом должна идти целочисленная переменная. Вторым аргументом тоже целочисленная переменная, а третьим аргументом -

388:20

Speaker C

строка. Ну и, соответственно, передаём тут 1 2ва и строка приветствую вас. Сохраняю, запускаю программу. Приветствую вас. Сумма а + b.

388:33

Speaker C

Ну и как мы видим, после приветствую вас не было переноса новой строки, потому что я вызвал инструмент print. Я, вообще-то, хотел бы, чтобы был перенос строки, поэтому использую инструмент printl. Запускаю. Теперь есть перенос на новую строку. Приветствую вас. Сумма а +

388:49

Speaker C

b = 3. То есть, мы в функцию сразу же передали несколько значений. Передали один, передали два и передали строковый тип. И вообще вот эти вот аргументы, их может быть сколько угодно, они могут быть каких угодно типов. Вот что вы

389:03

Speaker C

пожелаете, то тут и будет. Мы с вами дальше пройдём несколько более сложные типы переменных. И их тоже можно использовать как аргументы функции. То есть всё, что вы захотите, вы можете функцию передавать, благодаря чему она может выполнять какой-то определённый

389:18

Speaker C

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

389:35

Speaker C

кусок кода оставался тем же. И всё, что мы могли сделать, чтобы поменять поведение этого кода - это поменять значение переменной. Тут то же самое. Ну давайте опять же в конце я буду выводить пустую строку, чтобы нам разные вызовы

389:47

Speaker C

функций можно было визуально отделять. И вызову ещё раз сумм, например, 1033. И тут напишу, как дела, друзья. Запускаю программу. И мы видим, что мы просто написали в нашем коде, в нашей функции main, мы написали всего лишь две строчки. То есть программа

390:08

Speaker C

началась в восьмой строке, а завершилась в одиннадцатой. Но между восьмой и одиннадцатой строчкой программа два раза передавала управление другим функциям. В данном случае два раза было передано управление функцией сум с разными аргументами. Первый раз мы в неё передали 1 2 и приветствую вас. Она нам

390:25

Speaker C

вывела: "Приветствую вас" и сумму 1 + 2 = 3. Второй раз мы передали 1033. И как дела, друзья? у нас выявилось как дело, друзья. И 10 + 33 = 43. Порядок передачи аргументов важен, потому что если мы в

390:40

Speaker C

функции объявили, что мы вторым ожидаем именно целое число, то мы должны вторым передавать целое число. Если мы тут передадим строку какую-нибудь, привет, а тут передадим целое число, так не получится, потому что мы должны, если функции описали, что вторым ждём целое число, то передавать

390:58

Speaker C

туда именно целое число. Если описали, что третьим ждём строку, значит, туда нужно передавать строку. Если описали, что первым мы ждём целое число, точно также нужно передавать именно целое число. Если мы попробуем передать дробь, тоже не получится. Мы не можем

391:15

Speaker C

использовать флот там, где ожидался int, то есть мы не можем использовать дробное число там, где ожидалось целое число.

391:22

Speaker C

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

391:39

Speaker C

Это не какая-то переменная, это не какое-то там встроенное значение в язык, просто циферка, типа, ну, пять или вот это вот. Приветствую вас. Это тоже литерал, потому что это не значение, которое лежит в какой-то переменной. Вот это литерал, а вот это переменная. Это

391:56

Speaker C

литерал - это переменная. Это литерал- это переменная. Мы, когда вызываем наши функции, мы можем передавать туда не только литералы, мы можем передавать туда переменные. Давайте я это сделаю опять же на примере функции сам. То есть я объявлю переменную number 1, в неё я

392:13

Speaker C

положу пять. Объявлю переменную number 2, в неё я положу 10. и объявлю переменную текст. В неё я положу привет земляне и передам эти переменные в функцию сам number один, number 2. И сюда я передам текст. То есть мы

392:34

Speaker C

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

392:46

Speaker C

То есть, привет, земляне. Вот это значение, оно в одиннадцатой строчке положилось в переменную текст. Потом эта переменная текст передалась функцию сам и её значение оно скопировалось в переменную. И потом это значение привет земляне, оно вывелось на экран. То же

393:04

Speaker C

самое с переменными numberр 1 и number 2. Мы их передали в нашу функцию сам. Их значения скопировались в соответствующей переменной функции сам. То есть значение переменной numberр о, то есть пятёрка, скопировалась в переменную А. Значение number 2, то есть десятка, скопировалась

393:25

Speaker C

в переменную B. И у нас получилось 5 + 10, 5 + 10 = 15. Тут довольно важный момент для понимания. Я хочу, чтобы вы поняли, что когда мы вызываем таким образом функцию, то значения, которые мы передаём, они просто копируются. Это

393:45

Speaker C

обычная копия. Что это значит? Давайте сотрём всё, что мы до этого написали, чтобы на это не отвлекаться, и создадим какую-нибудь функцию, которая принимает разные значения, выводит их на экран.

393:55

Speaker C

Ну, я её назову фу, то есть какая-то, ну, бесполезная функция фу. Она будет принимать какую-то переменную n целочисленного типа и будет принимать какую-то переменную t типастing. Ну вот у нас уже функции суммы нет, потому что мы её удалили.

394:09

Speaker C

И тут я создам в мейне переменную number равна пяти и переменная текст равна привет. После этого вызову функцию F, передам в неё number и текст. А в самой функции F с полученными значениями я сделаю самое простое, что мы умеем - это

394:25

Speaker C

вывод на экран. Вот N двоеточие N и Т двоеточие T. Ну что ж, давайте запустим нашу программу. Ну, вроде пока всё понятно.

394:37

Speaker C

Мы создали переменную number, который присвоили значение пять. Мы создали переменную текст, который присвоили значение привет. Мы скопировали эти значения функцию фу. И, соответственно, переменная n у нас стала равна пяти, потому что мы в неё передали значение переменной number, а переменная Т у нас

394:55

Speaker C

стала равна привет, потому что мы в неё передали значение переменной текст. Но что будет, если мы внутри вот этой функции фу поменяем значение переменных N и T? Давайте в N запишем, например, 100, а в Т запишем меня поменяли, а потом выведем их ещё раз на

395:20

Speaker C

экран. N [аплодисменты] Т. Ну, давайте запустим нашу программу. Ну, пока всё ожидаемо. Типа мы приняли тут переменные, да, мы как бы их сначала вывели на экран, потом присвоили им новые значения и ещё раз вывели на экран, и у нас уже другие значения. Но

395:39

Speaker C

поменялось ли от этого значение переменных numberр и текст? Ну, давайте узнаем. То есть мы выведем переменную number до того, как мы вызвали функцию и переменную текст до того, как мы вызвали функцию.

395:56

Speaker C

И после, ну, я просто скопирую. Запускаем программу. И сейчас я попрошу внимательно на это всё посмотреть. У нас переменная number и переменная текст изначально равны пять и привет. И мы вводим, что у нас numberр п и текст равно привет. Вот numberр 5

396:18

Speaker C

текст равно привет. Потом мы вызываем функцию, в которую передаём значение этих переменных. Уже в функции мы выводим переменные N ит. Ну, соответственно, в Nли 5, N 5. В Т мы передали привет. Вот Т привет. Потом мы их поменяли. N ит вывели заново. N 100 Т

396:41

Speaker C

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

396:56

Speaker C

внутри этой функции поменяли эти переменные, да? Но наши переменные number и текст, которые были созданы в мейне, они свои значения не поменяли.

397:08

Speaker C

Numberр, как было пять в самом начале, так и осталось. Текст как было привет в самом начале, так и осталось. Что это может значить? Это значит только одно, что когда мы вызываем функцию и передаём в неё какие-то переменные, то мы на

397:25

Speaker C

самом деле передаём просто значения, которые лежат в этих переменных. Эти значения, они скопируются в переменные, которые у нас объявлены в аргументах функции, но сами переменные у нас останутся там, где есть. Если мы эти переменные, которые внутри функции, поменяем, от этого у нас переменные,

397:48

Speaker C

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

398:08

Speaker C

N было такое же значение, как у number, а у переменной T было такое же значение, как у текст. И всё. То есть переменная N и переменная Т - это не те же самые переменные, что у нас в мейне. Это

398:22

Speaker C

другие переменные. Это другие ячейки в памяти. Это другие области в памяти. Это совершенно другие переменные. Просто мы сказали языку программирования, что во время вызова функций я хочу, чтобы у этих переменных были значения такие, которые лежат под numberр и под текстом.

398:38

Speaker C

Но дальше, если ты будешь эти переменные как-то менять, это никакого отношения к переменным, которые у нас объявлены в мейне, не имеет. Поэтому мы тут можем спокойно вообще перезаписывать их 100 раз, разные им вообще значения передавать, там ля-ля-ля-ля-ля.

398:56

Speaker C

Но при этом всё равно в конце наши исходные переменные сохранят своё значение пять и привет, потому что, повторюсь, тут мы просто скопировали их значения в переменную n и в переменную t. Мы их не передали туда как бы напрямую. То есть это совершенно другие

399:15

Speaker C

переменные. Просто в начале выполнения функции они имеют значения, которые мы им задали. Эти значения просто скопировались, но далее при изменении этих переменных эффекта на переменные измейна это оказывать не будет. Осталось рассмотреть последний тип функций, которые не только принимают какие-то

399:35

Speaker C

значения, но ещё и могут эти самые значения возвращать. Давайте напишу простенький пример, на котором, на самом деле, многие объясняют функции, которые могут принимать и возвращать значение.

399:47

Speaker C

Это функция суммы. Особой логики она не несёт. Она нужна просто для демонстрации того, как вообще работает возвращение значений из функции. У нас есть а, у нас есть b и у нас есть какой-то непонятный int, который мы возвращаем. Типа что. И

400:04

Speaker C

я сейчас напишу следующую магию. Я сначала выведу на экран А, потом я выведу на экран B. Потом я в отдельную переменную запишу сумму A + B. и напишу return. Что тут случилось? Ну вот эту часть мы с вами

400:25

Speaker C

знаем. То есть мы тут по сути всё знаем, кроме вот этого инта непонятного вот этого вот и кроме return. Короче, вот у нас, значит, функция сум. Точно такой же кусок кода какой-то отдельный. Он принимает переменную А и переменную B.

400:38

Speaker C

Выводит эту переменную на экран. Сначала А, потом B, потом в переменную S кладёт сумму A + B и retтр S. Return с английского переводится как вернуть. То есть мы изнутри функции можем возвращать посчитанное значение в вызывающую функцию. Как это работает? Давайте я

401:00

Speaker C

сотру всё, что у нас было до этого. Вот я хочу просто создать какую-нибудь переменную, пускай она называется number, и пишу следующую магию. Я переменной присвоил не какое-то значение, как мы с вами раньше делали, там, да, там 123, например, или там 441.

401:19

Speaker C

Я присвоил переменной функцию. Как это работает? У нас есть функция сум. Ну, она принимает аргументы а и b. Вот я ей передал А. Вот я и передал B. Это мы с вами вроде как знаем. Потом она считает сумму а + b и

401:36

Speaker C

возвращает это посчитанное число изнутри себя. То есть я объявил здесь, что функция может возвращать целочисленный тип. И она это делает. Это значение записывается в переменную number. И в number я буду иметь a + b. Давайте выведем numberр на

401:58

Speaker C

экран. Сохраняю. Запускаю. А1 B2 number 3. Ну, давайте более подробно разберём, что тут вообще происходит. Сначала я напишу до вызова функции тут, после вызова функции. Ну и тут понятно, numberр на number. Давайте ещё раз запустим и разберём эту программку на

402:27

Speaker C

скриншоте. Ну, смотрим, у нас функция main. Это значит, что мы отсюда начнём своё выполнение. Первое, что делает функция main - это выводит на экран до вызова функции. Хорошо. Потом мы в переменную number хотим присвоить функцию сам. Но на самом деле мы не присвоим функцию

402:47

Speaker C

сам. Тут будет работать следующим образом. Язык программирования видит, что у нас вызывается функция сам и передаст ей своё управление. То есть сразу же управление будет передано в функцию сам. Функция сам у нас принимает один и 2. Соответственно, на место А

403:03

Speaker C

встанет один, на место B встанет два. У нас вывод соответствующий. Сначала мы вводим А, вот у нас выводится один, потом выводится B, выводится 2. После этого мы уже знаем, что мы умеем создавать переменные и класть в них значение. Соответственно, мы создаём

403:19

Speaker C

переменную S и кладём в неё значение A + B. Ну, A + B мы с вами знаем, что 3 равно, потому что в а лежит 1, а в B лежит 2. После этого функции написано return s. Это значит, что верни

403:31

Speaker C

результатом выполнения функции какую-то переменную. А что именно мы должны вернуть, описано в самом начале функции вот здесь вот. То есть то, что после объявления аргументов и до начала блока кода функции, всё вот, что тут написано, мы должны вернуть из функции. То есть мы

403:53

Speaker C

требуем здесь, чтобы из функции возвращался какой-то целочисленный тип integer. Мы должны из функции вернуть integer. И вот мы его тут возвращаем. Мы посчитали, что S у нас равно 3. S = 3. Вот здесь вот мы это присвоили. И возвращаем это самое три из

404:15

Speaker C

функции. То есть мы, давайте заново пойдём, вызываем функцию сам. Вот она вызывается, передаётся управление функцию сам. Она принимает 1 и 2. Эти 1 и 2 выводятся на экран вот здесь вот.

404:28

Speaker C

Потом мы считаем 1 + 2 = 3 и возвращаем вот это вот три. Потому что у нас вот тут вот описано, что мы должны вернуть какое-то целое значение, какое-то значение целочисленного типа. Это возвращённое значение, оно может быть присвоено какой-то переменной. И

404:46

Speaker C

выглядит это вот таким вот образом, что мы в переменную number кладём результат выполнения функции сам. Функция сам у нас приняла 1 и 2. В момент её вызова передалось управление этой самой функции. У нас тут один, тут два.

405:03

Speaker C

вывелась на экран, посчиталась сумма и вернулся результат. Вернулся и записался в переменную number. Почему он записался в переменную number? Ну, потому что мы этой самой переменной number присвоили результат выполнения функции сам.

405:19

Speaker C

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

405:36

Speaker C

возвращаемого значения, если оно им не нужно. Например, у нас функция, которая просто выводила на экран приветствие гостей. Вот это offici work. Нам ничего не нужно было возвращать, мы просто выводили на экран разный текст. А если нам нужно что-то возвращать, то мы

405:51

Speaker C

должны тип возвращаемого значения написать после аргументов и до начала открытия тела функции. То есть, если бы мы хотели вернуть строку, нужно было бы написать strтринг. Давайте посмотрим на функцию, которая бы у нас возвращала строку сумстринг. То есть у нас есть S1

406:09

Speaker C

типастринг, S2 типастринг, и мы бы возвращали тоже стринг. То есть мы просто бы возвращали сумму строк. Вот давайте я в переменную S положу сумму строк и верну эту переменную. То есть тут будет такая же абсолютная логика.

406:26

Speaker C

Вот это я удалю. Создам переменную текст 1, положу в неё hello и создам переменную текст 2.

406:35

Speaker C

Положу в неё world. Потом вызову сум передам туда текст 1, текст 2. И результат этой функции я положу в третью переменную текст 3. После этого выведу текст 3 на экран.

406:52

Speaker C

Сохраняю. Запускаю программу. 3 Hello World. Почему? Потому что у нас, вот я сюда её перемещу, у нас есть функция сум. Она у нас принимает две строки. Она эти строки берёт и складывает, сохраняет результат этого выражения в переменную S, а потом

407:11

Speaker C

возвращает эту переменную S. И тем самым мы можем использовать результат вот этой функции в переменной. Опять же рассмотрим на скриншоте. Мы создаём переменную текст 1 и текст 2. Потом передаём эти переменные в функцию. Вот у нас текст один. Вот у нас текст 2. То

407:30

Speaker C

есть в момент вызова функции сумстн у нас значения s1 и s2 будут такие же, которые лежат в текст 1 и текст 2. Почему? Да потому что мы их сюда просто взяли и передали. Мы могли сюда что угодно передать. Мы могли сюда

407:49

Speaker C

передать Абоба, Бибоба. Ну вот эти я удалю переменные, они не используются. Сохраняю, запускаю. Текстри. Абобабоба. Бибобабобабо. У нас взялось абобабо плюс Бибоба. Но мы вместо того, чтобы передавать сюда литералы, мы передали значение переменных. То есть то, что мы сюда

408:09

Speaker C

передадим, то и окажется в значении аргументов функции. Соответственно, мы сюда передаём текст один и текст 2. В текст один у нас лежит hello. Это значит, что в S1 будет лежать этот же Hello. В S2 мы передаём world. Это

408:27

Speaker C

значит, что здесь у нас будет world. Потом мы знаем, что у нас тут Hello, а тут у нас world. Ну и, соответственно, Hello + World равно Hello World. слитно, так как тут нигде нет пробелов. Hello world. Мы это Hello World возвращаем из

408:47

Speaker C

функции. Возвращаем как результат работы функции. То есть опять же здесь после объявления аргументов и до начала тела функции мы должны указать, что именно из этой функции будет возвращаться. Если ничего, тогда тут ничего не надо писать.

409:03

Speaker C

Но так как мы хотим вернуть строку, то мы пишем string и пишем return s. Это означает, что в двадцатой строчке у нас будет прекращено выполнение нашей функции и будет произведён возврат значения S. Соответственно, это S, оно у нас запишется в текст 3, потому что мы

409:23

Speaker C

именно тексту 3 присвоили результат выполнения функции сумстн. Ну, то же самое у нас было и с целыми числами, что мы принимаем с вами. А, мы сюда положили единичку, получается в А у нас единичка. B, в Bливоечку, получается, у

409:41

Speaker C

нас тут будет двоечка. Соответственно, 1 2. Вот у нас 1 2. Потом здесь в S, потому что 1 + 2 = 3. И возвращаем. То есть здесь функция завершает своё выполнение. И мы возвращаем эту самую троечку.

409:59

Speaker C

Возвращаем, объявляем, что мы будем возвращать именно целое число. И это самое целое число у нас вернётся и запишется в переменную number. Потому что мы, когда вызвали функцию, мы сказали, что результат выполнения этой функции запиши в переменную number.

410:14

Speaker C

Потом мы вывели numberр на экран и увидели, что там лежит тройка. То есть, повторюсь, return - это значит, что функция завершает своё выполнение и возвращает какое-то значение. Тип этого значения определяется тут. Если мы написали int, то мы уже не можем вернуть

410:33

Speaker C

туда строку. То есть, допустим, вот у нас тут строка, мы хотим вернуть целое число. Ну, допустим, return 10. А мы не можем, нам скажут, что мы не можем использовать целый тип как строку в возвращаемом значении. Ну, поэтому, если

410:48

Speaker C

мы тут написали, что у нас строка, то е возвращать тоже нужно строку. Соответственно, так какн у нас возвращает значение, завершает функцию, возвращает значение, мы после ретюрна уже ничего не можем сделать. Допустим, вот у нас сумстн. И тут я напишу

411:04

Speaker C

что-нибудь вывод на экран после ретюрна. Сохраняю. И нам даже не даст программа запуститься. Почему? Потому что мы наводим и нам пишет недостижимый код. Я даже попробую запустить. Давайте.

411:21

Speaker C

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

411:35

Speaker C

в двадцатой строчке, и тут уже ничего не будет. Мы можем написать ещё что-нибудь. Return там hello. Опять у нас недостижимый код. Но в этот раз уже программа хотя бы у нас запустится, но смысла это никакого не имеет, потому что

411:48

Speaker C

у нас всё равно недостижимый код. И у нас никогда не вернётся вот это вот значение, чтобы мы тут не писали. У нас всегда будет Hello World возвращаться, потому что возвращается он именно в 20цатой строчки один раз. Если мы уберём

412:00

Speaker C

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

412:18

Speaker C

это будет валидно. Ну, например, сделаем простую функцию, которая бы нам возвращала строчку без какой-либо логики. У нас есть вот функция, я её назову str, сокращённа от string, и она будет возвращать строку. Как мы видим, у нас функция может не принимать никаких

412:34

Speaker C

аргументов, но при этом возвращать какое-то значение. Ну и мы тут будем возвращать например это моя строка. Сохраняю и вызову эту функцию. Ну давайте запустим нашу программу, посмотрим, что вообще будет. А ничего не будет. А знаете, почему? Мы вызываем функцию str. Она нам

412:54

Speaker C

возвращает какое-то значение, какую-то строчку, но мы ничего с этим значением не делаем. Мы его даже нигде никуда не присваиваем. То есть у нас всё, что делает наша программа, это вызывает функцию STR. STR возвращает значение, которое мы никуда не присваиваем. И всё.

413:09

Speaker C

Что с этим делать? присвоить возвращаемое значение функцией str в какую-то переменную. Ну, я назову эту переменную S и выведу её на экран.

413:19

Speaker C

Сохраняю и запускаю. Что тут вообще произошло? Мы с вами вызываем функцию STR. STR нам возвращает строчку это моя строка. Мы результат выполнения функции str, то есть строчку это моя строка, записываем в переменную S и выводим эту переменную S на экран. Казалось бы, всё понятно,

413:38

Speaker C

всё просто, но я говорил, что у нас может быть в программе несколько ритюрнов. Как это может быть? Это может быть достигнуто, если у нас есть условное ветвление. Если в функции у нас несколько блоков кода, ну, к примеру, опять же, условное ветвление, то у нас

413:55

Speaker C

может быть несколько ритюрнов. Давайте создам булевскую переменную, которую назовут. Мы, в принципе, помним, что это значит, подписан ли на канал или нет.

414:06

Speaker C

Ну, сначала true и если subsc, тогда я верну. Ты подписан на канал, иначе я верну. Ты не подписан на канал.

414:27

Speaker C

Это я сотру. Опять же, это недостижимый код. Знаете, почему? Потому что у нас в обоих случаях условного ветвления наша функция заканчивает своё выполнение.

414:38

Speaker C

Поэтому у нас что subscrabed, что не subscriced, мы всё равно закончим своё выполнение, поэтому сюда мы уже никогда не попадём. Ну, вызываем нашу функцию, записываем результат её выполнения в переменную и выводим эту переменную на экран.

414:57

Speaker C

Ты подписан на канал? Почему? Потому что наша переменная subбс true. Если мы тут напишем false, тогда у нас выполнится блокса и вернётся: "Ты не подписан на канал".

415:11

Speaker C

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

415:28

Speaker C

чтобы было несколько ретюрнов, нужно условное ветвление. И тут уже наша задача, как программистов, понимать, когда нам нужно условное ветвление, когда оно нам не нужно, когда нам нужно возвращать какое-то значение, когда не нужно, когда нам нужно вообще создавать функцию, когда не нужно. И это всё

415:46

Speaker C

приходит только лишь с опытом. Вот так сразу, ну, не понять этого. Нужно сидеть, нарешивать разные задачи. Эти задачи должны усложняться. Вы должны себе сами что-нибудь придумывать. Ну или решать домашку, которую я дам. После этого начнётся у вас тренировка навыка

416:04

Speaker C

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

416:24

Speaker C

пяти, что-нибудь сделать, вы начнёте это всё чувствовать. Поэтому практика, практика, практика и ещё раз практика.

416:32

Speaker C

Так как мы с вами наконец-таки изучили концепцию функций, я бы хотел обсудить с вами две вещи. Первое - это функции, которая ничего не возвращает. О чём я говорю? Ну, мы помним, что у нас функции могут возвращать какие-то значения.

416:48

Speaker C

Допустим, у нас будет функция, которая называется square. Она будет принимать какое-то число и возвращать квадрат этого числа. То есть я в переменную S буду класть квадрат вот этого N. То есть нам приходит какой-то N, я возвожу его в

417:03

Speaker C

квадрат и запихиваю в переменную S. После чего я возвращаю значение, которое лежит в этой переменной S. Давайте посмотрим, как это выглядит. Я в мейне создам переменную квадрат и положу в неё результат выполнения функции square от пяти, после чего выведу это на экран.

417:24

Speaker C

квадрат квадрат. То есть мы вызовем функцию square, передадим в её аргумент пятёрку, то есть в переменной n будет лежать 5. Потом в переменную S я запихну квадрат пятёрки, то есть 25, и из функции square верну значение переменной S, то есть верну 25. Это 25 запишется в

417:45

Speaker C

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

418:05

Speaker C

слова return могуть какую-то переменную, какое-то значение, и это самое значение, оно вернётся из функции. О'кей? Но также мы можем вспомнить, что у нас есть функции, которые значения никакие не возвращают. К примеру, у нас есть [аплодисменты] функция. Что она делает? Она принимает

418:26

Speaker C

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

418:46

Speaker C

выведется привет, уважаемый Иван. Давайте посмотрим. Использование функции квадрат я удалю и вызову функцию, передав туда Иван. Сохраняю, запускаю. Привет, уважаемый Иван. Ну, всё, в принципе, логично. Мы вызвали функцию, передали в её аргумент значение, в переменную name, типа string, передали значение, и у нас

419:11

Speaker C

выявилось на экран. Привет, уважаемый Иван. Хорошо, давайте тут теперь попробуем написать Игорь. Запускаем. Привет, уважаемый Игорь. Ну, всё круто, всё вроде работает. А теперь представим, что мы сюда передали случайно или специально пустое имя, то есть как бы строку пустую, в которой

419:30

Speaker C

ничего нет. Буквально она только открывается, сразу же закрывается. Запускаем и видим. Привет, уважаемый. И, э, и всё. И, ну, никого у нас не вывелось. Какое-то странное приветствие.

419:43

Speaker C

Мы поприветствовали никого. На самом деле мы бы не хотели так делать. То есть перед тем, как выводить какое-то приветствие, мы бы хотели проверку ставить, что если у нас имя пустое, тогда говорить пользователю: "Вы передали пустое имя". Там поставить

420:02

Speaker C

грустный смайлик и не выводить никакого приветствия. Но если мы оставим всё как есть и передадим пустое имя, то у нас будет выводиться: "Вы передали пустое имя". Ну да. Да, то есть правильно, но потом всё равно будет приветствие происходить. Привет,

420:20

Speaker C

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

420:37

Speaker C

продолжать её выполнение, чтобы не выводить на экран привет, уважаемый никто. Как я могу это сделать?

420:44

Speaker C

Я могу написать ключевое слово return, мы с ним уже знакомы. Но до этого мы использовали retn функциях, которые возвращают какое-то значение для того, чтобы при помощи этого ритюрна, собственно, значение вернуть. Но если мы используем retтюрн в функциях, которые

421:01

Speaker C

ничего не возвращают, то это ключевое слово, оно просто прервёт исполнение нашей функции. То есть, что произойдёт?

421:09

Speaker C

Мы вызовем функцию, передадим туда, если пустое имя. У нас эта проверка вернёт истину. Мы провалимся в этот блок кода, выведем вы передали пустое имя и прервём выполнение нашей функции. Давайте посмотрим. Сохраняем файл, запускаем. Да, вы передали пустое имя.

421:28

Speaker C

Отлично. А если мы сюда передадим не пустое имя, например, Сергей. Запускаем. Привет, уважаемый Сергей.

421:36

Speaker C

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

421:52

Speaker C

достичь, если бы мы тут написали Элса, вывели приветствие в этом блоке Элса. И тут нам этот уже был бы не нужен. Но чем это чревато? Таких вот проверок у нас может быть не одна, может быть много, особенно если у нас сложная функция,

422:07

Speaker C

которая принимает множество аргументов. И таким образом, если мы вот таким способом будем очень долго ветвить нашу функцию, то мы придём к тому, что у нас очень много if, там name, что-нибудь там равно там такое-то. И в этом э ещё какой-нибудь

422:23

Speaker C

if, ещё какой-нибудь эса. И опять будем сталкиваться с проблемой большой вложенности. Поэтому это такой частый приём, что мы в начале функции, если хотим какую-то проверку произвести, какую-то валидацию передаваемых значений и прервать выполнение функции, если нам значение, переданное не подходит, то мы

422:44

Speaker C

просто в этой самой проверке пишем return. Тем самым мы прервём выполнение функции и избежим большого количества вложенности. Таким образом, в функциях, которые никакого значения не возвращают, просто прерывает выполнение этой самой функции. Тюрн в функциях, которые значения возвращают, возвращает какое-то

423:04

Speaker C

значение из функции. Ну, параллельно выполнение функции тоже в этот момент прервётся, потому что если мы из функции какой-то результат возвращаем, это значит, что наша функция в этот момент должна завершиться, чтобы этот самый результат отдать. О'кей. Вторая тема -

423:18

Speaker C

это глобальные переменные. До этого мы с вами рассматривали переменные, которые создаются внутри функции. То есть, если мы, например, внутри функции square создаём переменную S, то эта переменная S, она доступна только внутри этой самой функции Square. Почему? Потому что мы

423:36

Speaker C

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

423:55

Speaker C

ключевое слово war. После этого название переменной. Ну, например, у меня будет переменная number. После этого тип переменной integer. И можем какое-то значение ей сразу присвоить. Ну, например, пять. Таким образом, я благодаря тому, что создал переменную numberр типа integer вне всяких функций,

424:14

Speaker C

я создал глобальную переменную. В чём прикол глобальной переменной? В том, что она у нас доступна. Если смотреть в нашем примере, то во всех описанных функциях, то есть глобальная переменная, её область видимости не ограничивается каким-то куском кода. Поэтому эта самая

424:33

Speaker C

глобальная переменная, она у нас создаётся, как только программа запускается. И эта же самая глобальная переменная у нас удалится только тогда, когда завершится выполнение нашей программы. Например, вот переменная S.

424:47

Speaker C

Она создаётся в двадцать четвёртой строчке. И после того, как функция Square завершится, то переменная S удалится, потому что переменная S у нас принадлежит блоку кода. А вот глобальная переменная Number, она создастся в начале программы и удалится только в

425:05

Speaker C

самом конце программы. Поэтому это и называется глобальные переменные. Они доступны из всех описанных в нашем файле функций. И живут эти переменные на протяжении всего времени работы программы. Работа с этими глобальными переменными ничем не отличается от работы с обычными переменными. То есть

425:22

Speaker C

мы можем эти переменные выводить на [аплодисменты] экран. Я могу эту переменную перед выводом на экран умножить, например, на четыре функции main. Потом я могу вызвать функцию, передать туда даже пустое имя, но до проверки я переменную number поделю на два, а потом выведу на экран.

425:42

Speaker C

Давайте подумаем, что будет. Мы в самом начале нашей программы, как только мы запустили нашу программу, мы сразу же создали переменную number, глобальную переменную number. Потом началось выполнение нашей функции main, потому что мы помним, что функция main - это

425:58

Speaker C

основная функция, откуда начинается выполнение нашей программы. Первым делом в этой функции main я переменную number умножил на четыре. То есть переменна number изначально была пять, потом я умножил её на 4, стало 20. После этого я вызвал функцию. В функции гритинг первым делом

426:18

Speaker C

переменная number поделилась на 2. То есть у меня 20 поделись на 2, стало 10.

426:23

Speaker C

После этого тут произошёл какой-то вывод, и в мейне я вывожу на экран значение переменной number. Оно будет 10. Ну давайте проверим.

426:33

Speaker C

Сохраняю, запускаю. Да, number у нас 10. Почему? Потому что - это глобальная переменная. Она у меня доступна из любой функции, которая у нас вот в данном файле описана. И эта глобальная переменная, она создаётся во время запуска программы и удаляется только тогда, когда

426:52

Speaker C

программа завершает своё выполнение. Область применения вот этих вот глобальных переменных, она довольно ограничена, и обычно в них просто задаются какие-то значения, которые используются во многих частях программы.

427:06

Speaker C

Ну, к примеру, у нас какая-нибудь математическая там программа, и мы часто в нашей программе будем использовать число пи - это флот 64, то есть дробное число, ну, и оно там равно 3, 14 и так далее.

427:21

Speaker C

То есть мы вот это вот число пи захотим использовать в разных функциях нашей программы. У нас этих функций может быть много. И чтобы нам внутри каждой функции заново не создавать эту переменную, мы просто её делаем глобальной, благодаря чему она становится доступна из всех

427:38

Speaker C

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

427:58

Speaker C

[музыка] переменными. Следующая тема, которую мы разберём - это defe. Что вообще такое дефр, как он используется и что самое главное, для чего он вообще используется. Первым делом нам необходимо познакомиться с такой структурой данных, как стек. То есть, что вообще такое структура данных?

428:16

Speaker C

Структура данных - это какой-то формат хранения данных. Данные можно хранить абсолютно по-разному. Сейчас вам, наверное, это ни о чём не говорит, но просто держите в голове, что одни и те же данные можно хранить совершенно в разных видах. И вот одна из форм

428:32

Speaker C

представления вот этих самых данных - это стек. Сейчас мы разберём, что это такое. На самом деле всё довольно просто. Ну, думаю, многие из вас играли в покер, да? Представьте, что мы играем в покер, ну или хотя бы слышали. И у нас

428:45

Speaker C

есть фишки, которые стоят в стеке. То есть вот наш стек с фишками, да? Вот весь наш банк. И мы можем новые фишки, которые мы с вами выиграли, положить сверху этого стека, а можем взять сверху этого стека. Ну и, соответственно, вот

429:02

Speaker C

это наш стек с фишками в покере. По сути, стек с фишками в покере, он отлично показывает саму суть структуры данных стек. То есть стек - это какой-то набор данных, которые мы можем класть в него и забирать оттуда. Соответственно,

429:21

Speaker C

когда мы кладём какие-то данные в стек, они кладутся сверху новые данные. А когда мы оттуда забираем какие-то данные, они точно так же забираются сверху. То есть то, что мы в стек положили самым первым, оно оттуда достанется самым последним, потому что

429:39

Speaker C

нам до этого вот нужно добраться прямо до до вот этого последнего самого элемента. Вот мы до него добрались. Ну и, соответственно, когда мы в стек что-то кладём, оно кладётся снизу вверх, как горочка такая строится.

429:58

Speaker C

А потом, когда мы достаём что-то из стека, оно достаётся сверху вниз. То есть это и есть структура данных стек.

430:04

Speaker C

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

430:20

Speaker C

у нас есть функция main, и тут мы с вами выводим Hello 1. Потом мы тут можем вывести Hello 2, ну а потом Hello 3. Ну, запустим программу. Я думаю, ни для кого уже не будет секретом, что выведется Hello 1, Hello 2, Hello 3. А

430:36

Speaker C

теперь в начале этой функции я напишу de и вот такую вот конструкцию. Что тут вообще произошло? Я написал ключевое слово de, а после этого функ. Что тут случилось? До этого мы с вами проходили функции, и у нас были именованные

430:52

Speaker C

функции. То есть именованная функция - это какой-то кусок кода, который называется функцией, и у него есть название. Ну вот в данном случае это функция hello. А есть такое понятие, как анонимные функции. Это те же самые функции, выполняют ту же самую роль. Они

431:07

Speaker C

тоже могут принимать какие-то аргументы, тоже могут возвращать какое-то значение. Но у этих функций нету имени. Это анонимные функции. Анонимные функции как раз у нас используется, в частности, с дифром. Что это значит? Если мы напишем def, после него анонимную функцию и в

431:30

Speaker C

этой самой анонимной функции какую-то логику ну к примеру, я анонимная функция, то содержимое этой анонимной функции из-за того, что она написана после дефёра, будет выполнена в конце функции main. Ну давайте посмотрим, как это работает. Запускаем программу. И мы

431:51

Speaker C

видим, несмотря на то, что код, который выводит я, анонимная функция, написан самым первым, тем не менее выполнен он самым последним. Почему? Ну, для того, чтобы ответить на этот вопрос, давайте попробуем ещё больше дифёров написать, но уже в функции hello. Вот здесь вот в

432:09

Speaker C

функции main я в самом начале напишу я main и я начался. А здесь я напишу я main и я закончился.

432:23

Speaker C

функции hello. Я напишу я функция hello 1. Напишу тут три этих [аплодисменты] вывода и в самом начале функции hello я напишу то же самое, что и функция main, только тут напишу, что это именно функция hello. Сейчас я объясню, что я вообще

432:49

Speaker C

пишу, потому что я понимаю, что сейчас вообще ничего непонятно. Ну и тут мы вызываем функцию hello. Значит, так. Что вообще тут сейчас будет происходить? Давайте подумаем. Ну, у нас вызывается Printl в самом начале мейна. То есть можно предположить, что в самом начале у нас

433:06

Speaker C

программы выведется вот этот вот текст. Дальше у нас стоит diffфр. А, как мы с вами выяснили, фр у нас вызовет, то есть анонимная функция, которая идёт после дифёра, она вызовет, когда функция, из которой мы вызвали этот самый фёр,

433:24

Speaker C

завершится. То есть, если мы написали def в мейне, то тогда функция анонимная, которая идёт после дефёра, она отработает, когда закончится main. Если мы написали def в функции hello, тогда анонимная функция, которая идёт после фёра, она выполнится, когда hello

433:44

Speaker C

завершится. То есть, мы выводим: "Я main я начался". И поняли, что вот это выполнится, когда завершится main.

433:51

Speaker C

О'кей. Main перед тем, как завершится, ещё вызывает функцию hello. Хорошо, мы прыгаем в функцию hello. И тут я hello, и я начался. Ну, это значит и будет выведено. После этого у нас опять в дефёре вывод: "Я hello, я закончился".

434:05

Speaker C

Но мы уже с вами знаем, что то, что стоит после дифра, анонимная функция, которая стоит после дифёра, она выполнится, когда у нас будет завершаться функция, в рамках которой мы этот defфр прописали. Вот мы прописали def в рамках hello. Значит, вот эта

434:19

Speaker C

анонимная функция выполнится, когда hello завершится. Ну, хорошо. Значит, это выполнится у нас в конце Hello.

434:24

Speaker C

Дальше у нас я функция Hello 1, функция Hello 2 и я функция Hello 3.

434:33

Speaker C

После этого у нас заканчивается наша программа и начинается вызов функции, которая была написана после дефёра.

434:41

Speaker C

После фёра у нас вызывается функция, и всё, что в ней происходит - это вывод: я Hello и я закончился. Всё. После этого наша функция Hello завершается. После завершения функции Hello завершается и функция main, потому что после вызова функции Hello тут уже

434:58

Speaker C

ничего нету. И так как завершился, а мы в этом самом мейне задефрили вот эту анонимную функцию, она выполнится. Ну и у нас тут выведется: "Я main, я закончился". Ну давайте проверим нашу с вами догадку. Я main, я начался. Я Hello, я

435:17

Speaker C

начался. Hello 1 2 3. Я Hello, я закончился. Я, я закончился. То есть довольно удивительно, несмотря на то, что текст я и я закончился, мы вывели почти что в самом начале функции main до вот всей функции Hello. Тем не менее я main, я

435:36

Speaker C

закончился, вывелась у нас в самом конце. Почему? Потому что функция def, она откладывает вызов анонимной функции, которая идёт после этого ключевого слова defe. Давайте посмотрим, что будет, если я напишу несколько дефёров в одной функции. Ну, назову функцию фу, просто

435:51

Speaker C

фу. И тут будет у нас. Тут мы будем выводить def 1. Тут у нас будет def 2, ну и def 3. После этого напишем обычный вывод на экран фу. То есть у нас, когда функция фу начинает своё выполнение, она кладёт

436:18

Speaker C

раз def, два def, 3 def, то есть совершает три отложенных вызова. Ну и после этого просто выводит на экран фу.

436:24

Speaker C

Давайте посмотрим, что будет, если мы вызовем вместо hello fu начался. Фур 32. Яй, я закончился. Ещё что мы плюс-минус можем понять, это почему Яain я начался, выявилось в самом начале и Ямей я закончился, вывелось в самом конце, потому что мы в самом начале

436:47

Speaker C

нашей программы вывели я main я начался. И в отложенном вызове мы вывели яa я закончился. То есть я main и я закончился выведется только тогда, когда main действительно у нас закончится. А main у нас закончится в самом конце,

437:02

Speaker C

потому что это самая главная функция в нашей программе. Ну, соответственно, в самом начале выводится я начался, потом я закончился. А что вот тут произошло?

437:10

Speaker C

Мы вызвали функцию hello. В этой функции hello мы сначала напихали три отложенных вызова, потом вызвали фу. Ну, хорошо, мы с вами поняли, что когда мы пишем def, то код, который после дифёра написан, он выполнится не сразу же, а выполнится

437:26

Speaker C

только, когда функция фу у нас будет завершаться. То есть, если мы вызвали deфр в рамках функции F, то вот эти отложенные вызовы, они будут вызываться, они будут исполняться только когда уже функция фу будет завершать своё выполнение. Ну, о'кей, напихали три

437:41

Speaker C

отложенных вызова, вывели фу. Ну, соответственно, мы, когда отложенные вызовы пихали, мы ничего не выводили при этом. Мы просто отложили вызов вот этих вот функций анонимных и выводим printl.

437:54

Speaker C

Хорошо. Ну, у нас заканчивается функция фу и начинается исполнение наших отложенных вызовов, но почему-то они выполняются в обратном порядке. Мы сначала отложили def 1, потом отложили def 2, потом отложили def 3, а выполнились они сначала три, потом два,

438:11

Speaker C

потом один в обратном порядке. Почему так произошло? Мы с вами не случайно в начале разобрали структуру данных стек.

438:18

Speaker C

И когда мы с вами пишем def откладываем выполнение какой-то анонимной функции, эта самая анонимная функция кладётся в стек отложенных вызовов. Что это такое?

438:29

Speaker C

То есть мы с вами разобрали, что такое стек. Ну, теперь мы можем с вами, в принципе, понять, что такое стек отложенных вызовов. Каждый раз, когда мы пишем какой-то фр, то наша функция кладётся в стек. Вот мы написали, значит, defор 1, мы его самым первым

438:47

Speaker C

отложили. Получается, у нас это самое diф 1 отложится в стек как первая фишечка. После этого мы откладываем вызов def 2.

439:01

Speaker C

И это def 2 отложится тоже в наш стек очередная фишечка. Def 2. Потом у нас с вами идёт def 3, def 3 тоже откладывается в стек вызовов. После этого у нас выводится фу на экран и завершается функция фу. После

439:22

Speaker C

того, как функция фу завершается, наша программа начинает смотреть на то, нет ли случайно каких-то отложенных вызовов для функции фу. Они есть, их целых три штуки. И пойдёт наша программа смотреть на эти отложенные вызовы в структуру данных СТЕК. Именно поэтому мы с вами

439:42

Speaker C

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

439:51

Speaker C

Клали мы их снизу вверх 1 2 3. А доставаться они будут сверху вниз. 3 21.

439:57

Speaker C

Поэтому у нас сначала из этого стека возьмётся def 3 и выполнится. Потом только def 2 и потом def 1. Ну, мы это можем с вами видеть и выводе. Сначала 3 вызвался, потом def 2, 1. То есть мы каждый раз, когда в нашей функции фу

440:13

Speaker C

встречались с дифром, то мы в этой функции делали отложенный вызов. Этот отложенный вызов клался в стек отложенных вызовов. И, соответственно, то, что мы самое первое отложили, положилось в самый низ. Потом то, что мы второе отложили, положилось выше. Третье

440:28

Speaker C

отложили, положилось ещё выше. Но когда функция завершает своё выполнение, она обращается к этому стеку отложенных вызовов и смотрит, нет ли там чего-то.

440:37

Speaker C

Если там что-то есть, она начинает это выполнять сверху вниз, потому что структура данных стек предполагает, что мы кладём снизу вверх, а достаём сверху вниз. Ну и, соответственно, у нас сначала def 3, потом def 2, потом def 1.

440:52

Speaker C

Def, повторюсь, у нас будет класть в стек отложенных вызовов для той функции, в которой мы этот самый фр вызвали. То есть, если мы вызвали deфр в мейне, то эта функция анонимная будет положена в обратный стек вызовов функции main. Если

441:09

Speaker C

мы вызвали def функции Fu, то функция анонимная, которая после дифра идёт, будет отложена в обратный стек вызовов функции фу. Это значит, что у нас вот эти дефёры будут выполняться именно в конце функции F, а вот этот фёр будет

441:24

Speaker C

выполняться именно в конце функции main. То есть def он имеет прямое отношение к той функции, в рамках которой он вызывается. То есть вот этот вот def, который функции hello, он вызовет именно когда функция hello закончится, потому что он был положен в стек обратных

441:39

Speaker C

вызовов именно функции Hello. Почему именно функции Hello? Да потому что он в этой самой функции был написан. Вот мы с вами узнали, что такое фр, что это просто отложенный вызов какой-то анонимной функции. Эта анонимная функция вызовется, когда функция, в рамках

441:54

Speaker C

которой мы прописали deфр, завершится. Мы с вами узнали, что фр выполняется в обратном порядке. То есть, если мы отложили сначала def 1, потом deфр 2, потом def 3, то выполнятся они в обратном порядке, потому что они содержатся в структуре данных стек. А

442:09

Speaker C

как мы узнали, структура данных стек очень похожа на обычный стек фишек в покере. Кладём мы фишечки снизу вверх по одной, а доставать мы их будем наоборот сверху вниз. Ну, как в обычный стек в покере. Давайте теперь поговорим про то,

442:26

Speaker C

зачем вообще нам этот дефёр нужен. Давайте представим, что мы используем функцию, которая у нас входит в базу данных. Я назову эту функцию database.

442:35

Speaker C

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

442:48

Speaker C

database, которая вызывается в мейне. Ну вот пускай у нас останется ямей, я начался, яй, я закончился. У нас есть функция database, которая входит в базу данных. Для того, чтобы нам сходить в базу данных, нам нужно создать какое-то подключение. Ну, то есть создать

443:03

Speaker C

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

443:18

Speaker C

мы завершили работу с базо данных, нам нужно это самое подключение закрыть. Для чего? Для того, чтобы у нас не копились эти открытые подключения. Для того, чтобы они рано или поздно не закончились. Потому что если подключение у нас закончатся рано или поздно, то

443:31

Speaker C

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

443:49

Speaker C

циклы. В этих циклах тоже какое-то условное ветвление. И в каждом из этих условных ветвлений у нас что-то происходит. И при этом функция завершается. Хорошо. То есть у нас задача каждый раз, когда мы взываем функцию database, в самом её

444:06

Speaker C

начале создать подключение, а в конце закрыть подключение. Но представим, что мы завершили своё выполнение вот здесь вот в двадцать девятой строчке, но мы тогда не достигли сорок четвёртой строчки, мы тогда не закрыли подключение. Ну хорошо, получается, нам здесь перед ритюрном, перед тем, как

444:22

Speaker C

функция у нас завершится, нам необходимо закрыть подключение. Хорошо. А теперь представим, что мы вот здесь вот с вами завершились случайно и до сюда опять не дошли. Хорошо, тут тоже нужно закрывать подключение. И тут нужно закрывать подключение. То есть нам нужно следить

444:38

Speaker C

своими глазами, где у нас функция может завершиться. И в каждом из этих мест нам нужно прописывать закрытие подключения.

444:46

Speaker C

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

445:02

Speaker C

закрытию подключения. А что мы можем сделать? Мы можем в самом начале функции database задефёрить это самое закрытие подключения, то есть закрыть подключение в ффюре. Что это нам даст? Это нам даст, что язык программирования сам будет следить, где функция завершается, и в

445:24

Speaker C

этом месте будет сам вызывать вот этот вот дефёр. Получается, нам уже не нужно следить за тем, где именно у нас заканчивает выполнение наша функция. Мы обязательно вызовем закрытие подключения, когда у нас закончится функция database. Почему? Потому что мы

445:42

Speaker C

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

445:58

Speaker C

вот в сорок шестой? У нас в любом случае вызовет отложенная функция. У нас в любом случае произойдёт отложенный вызов, и мы в любом случае закроем подключение. То есть это один из самых частых примеров использования функции de. Таким образом, мы с вами разобрали,

446:14

Speaker C

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

446:35

Speaker C

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

446:53

Speaker C

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

447:04

Speaker C

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

447:20

Speaker C

строка. И это самое нечто большее может занимать очень много памяти. Так вот, представим, что у нас есть вот такая переменная, и мы хотим передать её в какую-нибудь функцию. То есть, напоминаю, когда мы с вами прописываем какую-то функцию, и она принимает

447:37

Speaker C

какой-то аргумент. Например, вот мы принимаем переменную А и выводим её на экран. Вот тут создаём какую-нибудь переменную типа number и вызываем функцию fu, в которую мы передаём переменную. Вот в этот момент, когда мы вызываем функцию фу и передаём в неё

447:53

Speaker C

какую-то переменную, то эта переменная у нас копируется, то есть копируется её значение. Соответственно, переменная А создаётся новая, и в неё копируется значение, которое мы передаём. Поэтому, если у нас есть какая-то функция, которая принимает переменную, то это значение у нас будет копироваться. То

448:10

Speaker C

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

448:26

Speaker C

делать, тем больше места в памяти она будет занимать. Это первая проблема, что копии многочисленные этой переменной будут занимать слишком много памяти.

448:35

Speaker C

Вторая проблема в производительности. Скопировать такой большой объект, скопировать такую большую переменную, это требует процессорного времени.

448:45

Speaker C

Поэтому, чем больше наша переменная, чем чаще мы её копируем в нашей программе, тем хуже для нашей самой программы. Тем больше наша программа занимает оперативной памяти и тем медленнее наша программа работает. Поэтому копировать просто такие огромные переменные - это

449:05

Speaker C

неэффективно. В таких случаях, когда у нас есть в памяти какой-то огроменный объект, какая-то огроменная переменная, и мы хотим эту самую огроменную переменную использовать в разных местах нашей программы, для таких случаев придумали указатели. Что такое указатель? Указатель нам позволяет иметь

449:25

Speaker C

доступ к какому-то объекту в памяти, какой-то переменной. При этом у нас нет необходимости этот самый большой объект копировать. И сам указатель весит в памяти немного. То есть, что мы имеем в итоге? У нас есть какая-то сущность, которая называется указатель, и она

449:43

Speaker C

весит в памяти мало места. Мы этот указатель можем передавать в разные наши функции, использовать в разных местах нашей программы. И с помощью этого указателя мы можем получать доступ к нашему огромному объекту в памяти. Что это нам даёт? то, что мы для того, чтобы

449:59

Speaker C

в разных местах нашей программы, в разных функциях нашей программы работать с этим огромным объектом, мы избавлены от необходимости этот огромный объект копировать. Мы можем просто заводить указатели, с помощью которых будем обращаться к исходному объекту. В чём выигрыш? Это в том, что у нас огромная

450:17

Speaker C

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

450:36

Speaker C

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

450:51

Speaker C

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

451:08

Speaker C

работать и не изменять исходный объект в памяти. Но если нам достаточно просто иметь доступ к исходному объекту в памяти, то указатели для этого отлично подходят. То есть, ещё раз, что такое указатели? Это переменные. То есть указатель - это тоже переменные. Это

451:24

Speaker C

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

451:41

Speaker C

пока мы ещё не в состоянии его полностью осознать, поэтому вам опять же придётся мыслить чуть на более абстрактном уровне и отчасти верить не на слово. Есть такие объекты у нас в языке программирования, которые мы не можем просто взять и

451:56

Speaker C

скопировать функцию, потому что в таком случае работа с этими объектами будет неверная. Что это могут быть за объекты?

452:04

Speaker C

Опять же вспоминаем тот же самый коннекшн к базе данных, подключение к базе данных. Подключение к базе данных по своей сути это тоже какая-то переменная, просто у неё более сложный тип. Не просто какое-то число, а более сложная структура. Так вот, когда мы

452:19

Speaker C

через этот коннекшн, через это подключение работаем с базой данных, то нам всегда необходимо пользоваться одним единственным подключением во всех местах нашей программы, где мы это самое подключение вызываем. Почему? Потому что это подключение, оно под капотом регулирует доступ к базе данных. И если

452:39

Speaker C

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

452:53

Speaker C

Потому что сама переменная, сам объект подключения должен быть одним единственным. И мы из всех мест программы должны работать с одним единственным объектом подключения к базе данных. Это я говорю с некоторыми допущениями, но пока на таком простом уровне просто для понимания. И поэтому в

453:11

Speaker C

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

453:29

Speaker C

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

453:44

Speaker C

используются указатели в программировании? Первое - это возможность избавиться от необходимости копировать огромные объекты в оперативной памяти. И мы тем самым, избегая копирования, экономим оперативную память и экономим процессорное время. То есть наша программа занимает меньше памяти и работает быстрее, потому что мы при

454:04

Speaker C

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

454:18

Speaker C

исходную, если мы с помощью одного указателя поменяем эту переменную, то она изменится и для всех других указателей, потому что они указывают на вот эту переменную.

454:30

Speaker C

Поэтому, если нам нужно в разных местах нашей программы создать независимые копии какого-то объекта, какой-то переменной, тогда указатели нам не подойдут. Но если нас устраивает, что все указатели будут указывать на одну переменную, и мы в одном указателе её можем как-то поменять, и это увидит все

454:49

Speaker C

другие указатели, тогда, конечно, тоже отлично подходит указатель. И это его свойство этого самого указателя, что если один указатель взаимодействует с переменной, то другие указатели тоже будут видеть эти изменения. Это нам полезно для таких случаев, как работа с базой данных. Потому что, если мы с

455:06

Speaker C

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

455:23

Speaker C

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

455:42

Speaker C

использовать указатели, которые будут указывать на объект подключения к базе данных. Ну, я понимаю, что это сейчас примеры вообще с потолка для вас с подключением к базе данных, потому что мы ещё с этими подключениями не работали. Вы в принципе слабо себе

455:56

Speaker C

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

456:11

Speaker C

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

456:27

Speaker C

памяти, а просто создать на него маленький указатель, с помощью которого у нас будет доступ к этому объекту. И указатели нам помогают в разных местах программы работать с одной и той же переменной. Опять же, для чего? Ну, например, для подключения к базе данных.

456:41

Speaker C

Вот такая минимальная теория по указателям. Мы к этой схемке ещё будем возвращаться, но давайте сейчас перейдём к коду и попробуем как-то осознать вообще эти указатели на практике. И давайте посмотрим вообще на синтаксис создания указателей. Ну, для начала создам обычную переменную number. Мы, в

456:58

Speaker C

принципе, уже много раз это делали. Самая обычная переменная number. То есть пускай вот эта самая наша переменная numberр - это вот эта вот переменная в памяти. Ну, так как это число, а не какая-то там огромная переменная в памяти, я вот её поменьше вот так вот

457:12

Speaker C

изображу, что вот этот наш оранжевый квадратик - это наша переменная number. Вот она. Это вот наша переменная number.

457:20

Speaker C

Теперь давайте создадим указательно переменную number. Указатель по-английски будет pointer, то есть, ну, назвать можно как угодно переменную.

457:29

Speaker C

Опять же я назову её pointer, чтобы наши названия переменных были осмысленными. И вообще советую вам всегда придерживаться такой концепции, что когда вы как-то называете переменные, то нужно давать им осмысленное название, чтобы потом, когда вы сами в свой код смотрели или когда

457:44

Speaker C

другие люди будут ваш код читать, например, ваши коллеги по работе, чтобы они сразу понимали, для чего те или иные переменные были созданы. Потому что называть переменные А и B - это, конечно, круто, но потом ничего непонятно становится. Поэтому я назову

457:59

Speaker C

переменную Pointer с английского это указатель, и присвою ей, собственно, указатель на переменную Number. Что тут произошло? Я создал переменную Pointer и положил в неё указатель на переменную Number. То есть поставил ампер и написал number. Что это значит? То, что я взял

458:17

Speaker C

указатель на переменную number и положил этот указатель в переменную поinter, то есть вот этим вот синтаксисом персант и название переменной. Я сказал языку программирования, что я хочу создать какой-то указатель, и указывать он будет именно на переменную, название которой я

458:38

Speaker C

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

458:52

Speaker C

[аплодисменты] видим какое-то непонятное число. Что это такое? На самом деле это адрес в памяти.

459:02

Speaker C

Что именно за адрес в памяти? Это адрес нашей переменной number. Адрес той переменной, на которую мы с вами взяли указатель. То есть вот это это адрес вот этой вот нашей переменной. Наша переменная number лежит по вот этому адресу. То есть мы чуть-чуть поближе

459:21

Speaker C

познакомились с указателями. теперь и поняли, что указатели они, по сути, из себя представляют адреса переменных в памяти. То есть указатель - это тоже просто переменная, которая в себе содержит значение адреса какой-то другой переменной. Для чего? Да того, чтобы мы

459:41

Speaker C

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

459:59

Speaker C

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

460:14

Speaker C

к базе данных. И мы не можем просто так взять его и скопировать как аргумент функции. Вот указатели отлично для этого подходят. То есть указатель - это просто какой-то адрес в памяти. Это переменная, которая хранит адрес памяти. Какой адрес

460:28

Speaker C

памяти она будет хранить? Адрес памяти той переменной, на которую указатель указывает. Благодаря этому механизму, в принципе, реализуема концепция указателей, что мы можем какую-то маленькую переменную передать, а потом с помощью этой маленькой переменной иметь доступ к большим каким-то объектам. Да,

460:45

Speaker C

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

460:54

Speaker C

Вот наша обычная самая переменная целочисленного типа небольшая. И мы взяли на неё указатель Pointer. Хорошо, мы поняли, что мы взяли указатель на переменную Number. Указатель - это какой-то адрес памяти. Что мы можем с этим делать дальше? Сейчас мы рассмотрим

461:11

Speaker C

несколько примеров использования указателей. Они на первый взгляд могут показаться неочевидными. Но нужно привыкать. Плюс сразу же вас предупрежу, что вот этот вот синтаксис работы с указателями, он довольно странный, то есть он непривычный, он не очевидный. Я, честно признаться, даже

461:29

Speaker C

сейчас иногда путаюсь в этом синтаксисе указателей. Вот, честно прямо не могу запомнить иногда, когда что нужно написать, и просто методом тыка вспоминаю, что же всё-таки нужно поставить. Сейчас я объясню, о чём речь.

461:43

Speaker C

Смотрите, допустим, мы вот с вами создали этот указатель и хотим им воспользоваться так, как я приводил примеры. То есть у нас есть какая-то функция отдельная, и мы хотим в эту функцию передать наш указатель. Потом с помощью этого указателя получить доступ

461:58

Speaker C

к исходной нашей переменной. Ну давайте я создам функцию, которая бы принимала указатель. Функцию назову фу, и она будет принимать указатель. Смотрите за руками, как говорится, и не пугайтесь.

462:10

Speaker C

[аплодисменты] Что я тут написал? Я тут написал, что функция фу будет ожидать переменную n, ну, аргумент n, который является указателем на тип данных int. То есть мы помимо того, что должны, в принципе, указать, что мы ожидаем указатель, мы

462:29

Speaker C

должны ещё указать, на какой тип данных этот указатель будет указывать. Потому что указатель на тип данных in и указательно тип данных string - это два разных указателя. Они под собой несут одну и ту же логику. То есть то, что я

462:46

Speaker C

объяснял, оно не привязано к какому-то конкретному типу указателя и распространяется на все типы указателей, которые вы, в принципе, можете в программе создать. Но так как у нас го - это язык статически типизированный, то мы должны придерживаться не только типов

463:03

Speaker C

переменных, но и типов указателей. Поэтому тут мы должны указать, какой тип указателя мы ожидаем. Мы ожидаем указатель на тип данных integer. Почему?

463:13

Speaker C

Ну, потому что мы используем integer сейчас в примере. Что это вообще за звёздочка? Звёздочка говорит, что тут будет указатель. Звёздочка помогает языку программирования отличить, когда мы в функции ждём просто переменную типа int от случаев, когда мы функции ждём

463:32

Speaker C

именно указатель на тип int. Вы спросите меня, почему в восьмой строке мы, когда создавали указатель, мы написали амперсант, а в тринадцатой строке мы, когда ожидаем указатель, мы написали звёздочку. Я вам могу, конечно, объяснить, но повторюсь, я сам до сих

463:49

Speaker C

пор путаюсь и забываю. во время написания кода, что мне нужно поставить: амперсант или звёздочку? Амперсант - это значит, что мы берём адрес у переменной.

464:01

Speaker C

То есть вот так вот создать указательно переменную по сути своей, если дословно, так сказать, разбирать каждый символ, то мы берём именно адресу переменной. То есть амперсант, после которого идёт название переменной, означает, что мы хотим взять адрес этой переменной. И

464:18

Speaker C

адрес переменной number мы кладём в переменную Pointer, которая, если навести, как раз и будет указателем на целочисленный тип данных, то есть указателем на нашр. Вот когда мы берём адрес, именно операция взять адрес, то есть когда мы хотим сказать языку

464:34

Speaker C

программирования: "Дай мне адрес переменной", то нужно написать амперсан и после него название переменной. Ну, в данном случае number. То есть вот этот синтаксис говорит о том, что мы берём указатель на number. Когда же мы пишем просто звёздочка int или звёздочка

464:51

Speaker C

stringн или звёздочка любой другой тип. Вот подобным образом это значит, что представленный тип данных является указателем на какую-то переменную, в данном случае указатель на int. К этому синтаксису нужно просто привыкнуть, что когда мы пишем амперсант и после него

465:06

Speaker C

название переменной, это мы берём адрес какой-то переменной. А когда мы пишем звёздочка in, звёздочка string, звёздочка любой другой тип, это означает, что мы просто ожидаем тут увидеть тип данных указательно int. То есть звёздочка in - это указательно int.

465:23

Speaker C

Ampersant number - это мы берём указательно number. С этим просто нужно свыкнуться. Так вот, создали мы функцию F. Принимает она указатель на int. Этот указатель на int называется N. Что мы можем с этим N сделать? Мы можем вывести

465:38

Speaker C

его на экран. Вот давайте выведу на экран. То есть тут я буду вызывать функцию F и передавать в неё поинтер. То есть создали целочисленную переменную, взяли адрес этой переменной и положили в другую переменную поинтер и вызвали функцию F,

465:54

Speaker C

в которую этот самый поинтер передали. В функции фу мы этот поинтер принимаем и выводим на экран. Ну, вывод, в принципе, будет очень похожий, но немножко другой.

466:04

Speaker C

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

466:21

Speaker C

адрес не особо интересует. Мы можем просто посмотреть, что эти адреса отличаются. Но конкретная цифра конкретно, где это находится в оперативной памяти, нам, если честно, не особо интересно. Вот мы поняли, что мы функцией фу приняли указательно int, вывели его на экран и то, что это просто

466:37

Speaker C

какой-то адрес в памяти. О'кей. А как нам вывести не указатель, да, не адрес памяти, который в этом указателе хранится, не адрес памяти переменной, на которую этот указатель указывать? Как вывести само значение этой переменной?

466:52

Speaker C

То есть я же вначале сказал, что мы с помощью указателей можем получать доступ к исходной переменной. Ну давайте я покажу, как это делается. В следующей строчке мы выведем значение, которое лежит по этому указателю. То есть вот у нас указатель N. Вот наш указатель. И

467:08

Speaker C

сейчас мы выведем значение, которое лежит в переменной, на которую этот указатель указывает. Для этого перед указателем нужно написать звёздочку.

467:20

Speaker C

Запускаем и видим, что сначала у нас выводится адрес памяти, а потом значение, которое лежит под этим указателем. Это называется разыменовывание указателя. Почему звёздочка? Ну, так принято со времён ещё си, что разименовать указатель - это нужно перед ним написать звёздочку. Что

467:40

Speaker C

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

467:57

Speaker C

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

468:14

Speaker C

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

468:30

Speaker C

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

468:45

Speaker C

получить доступ к переменной, которая по этому самому указателю лежит. А теперь давайте я покажу некоторую магию. Как вы помните ранее, у нас, если какая-то функция принимает переменную внутри себя, эту переменную меняет, то это никакого влияния на ту переменную,

469:03

Speaker C

которую мы в эту функцию передали, не оказывает. То есть, к примеру, вот это вот я закомментирую. То есть, к примеру, мы вот создаём переменную number, кладём в неё пять и вызываем функцию бу. И в неё я передаю этот самый numberр. То

469:18

Speaker C

есть функция бу у нас принимает аргумент типа integer и кладёт в него число 10.

469:25

Speaker C

Соответственно, я создал переменную number, положил в неё пятёрку, вызвал бу и после этого хочу вывести на экран значение этой самой переменной number.

469:36

Speaker C

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

469:55

Speaker C

переменной number. То есть мы, когда вызвали функцию бу, создалась новая переменная n, и в неё скопировалось значение пять. И то, что мы тут поменяли, мы на самом деле поменяли просто вот эту переменную N, которая существует только в рамках функции бу.

470:10

Speaker C

Переменную number мы при этом никак не затронули. Но если мы берём указатель на переменную number, передаём этот указатель в функцию и в функции мы поменяем переменную, которая лежит под этим указателем, то это уже окажет влияние на исходную переменную. Давайте

470:35

Speaker C

посмотрим. То есть у нас в функцией фу вывелся наш указатель, то есть наш адрес в памяти. Потом вывелось значение, которое лежит по этому адресу в памяти.

470:45

Speaker C

Потом мы написали какую-то непонятную фигню и в конце вывели numberр. И numberр стал у нас 10. Почему так произошло? Мы в восьмой строчке создали указатель на переменную number. То есть мы создали вот этот вот самый указатель.

471:03

Speaker C

Вот он наш указатель. Мы его создали в восьмой строке. И потом мы вот этот вот самый указатель передали в функцию фу. Вот мы его создали. Вот мы функцию фу передали указатель. Функция фу этот указатель приняла и вывела его

471:19

Speaker C

на экран. Это просто адрес памяти. То есть вот наш указатель, его вывели на экран. Это просто адрес памяти. Потом функция фу разименовала указатель и посмотрела, что же там за значение лежит под этим указателем.

471:35

Speaker C

И в семнадцатой строчке мы вывели значение переменной, которое под этим указателем лежит. А в девятнадцатой строчке мы с вами разыменовали указатель, то есть опять же разыменовали указатель, перешли от указателя к самой переменной, на которую он указывает, и туда положили значение. То есть мы по

471:56

Speaker C

этому указателю перешли к переменной и поменяли значение, которое лежит внутри этой переменной, вот такой вот записью.

472:04

Speaker C

И поэтому, когда функция фу завершает своё выполнение, значение переменной number изменилось, потому что мы с помощью указателя, который мы передали функцию фу, поменяли изнутри функции значение переменной. Сейчас скажу вещь, которая очень трудно ляжет ваш мозг. Я в этом почти уверен, потому что я сам

472:27

Speaker C

очень долго доходил до этого. Но мы знаем, что указатели - это тоже переменные. Просто тип такой переменный указатель. Так вот, когда мы передаём указатели в функцию, то мы создаём копию указателя. Точно так же, как когда мы передаём в функцию какую-то переменную.

472:47

Speaker C

Мы эту переменную копируем. Также, когда мы передаём в функцию какой-то указатель, этот указатель также копируется. Что у нас на самом деле произошло в нашей программе? Давайте я удалю все другие указатели, которые нам тут мешают. Вот в шестой строчке мы

473:04

Speaker C

создали переменную number, а в восьмой строчке мы создали первый указатель на эту самую переменную. Потом, когда мы в десятой строке вызвали функцию F и в неё передали вот этот вот указатель Pointer, то на самом деле мы этот указатель

473:20

Speaker C

скопировали. Что это значит? Что функции фу, когда мы её вызвали, в ней создался ещё один указатель, но с тем же адресом в памяти. Поэтому этот самый указатель указывает на ту же самую переменную.

473:35

Speaker C

Поэтому указатель вот этот вот, который у нас функции main и указатель функции F - это два разных указателя, но они указывают на одну и ту же переменную, на одну и ту же область памяти. Так вот, мы передали функцию F наш указатель, он тут

473:49

Speaker C

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

474:14

Speaker C

этого скопированного указателя изнутри функции смогли подменить значение переменной, на которую мы указываем. И теперь, если мы в мейне разыменуем указатель поinterтер, ну, давайте я вот напишу разыменовывание.

474:29

Speaker C

[аплодисменты] Pointer. И тут просто в выводе с помощью разименования, но уже не через скопированный указатель, а через оригинальный указатель, с помощью разыменования дойду до переменной, на которую мы указываем, вот таким вот образом. И запущу программу, то мы увидим, что разыменование Pointer тоже

474:52

Speaker C

ведёт к десятке. Почему? Потому что мы с помощью скопированного указателя поменяли нашу переменную, на которую мы указываем, положили туда десятку вместо пятёрки, а потом в мейнейне с помощью исходного указателя также разименованием дошли до этой же переменной. Ну там, ну

475:12

Speaker C

десятка лежит, потому что это та же самая переменная, мы на неё уже указываем. С помощью другого указателя мы эту переменную поменяли, поэтому мы теперь во всех других указателях будем видеть этот результат. Соответственно, вот разыменование поинте тоже 10. Хотя

475:24

Speaker C

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

475:43

Speaker C

вообще не очевидно, максимально странно. Какие-то у нас перемены, какие-то адреса в памяти, какие-то указатели. Что там можно разыменовывать, что там можно брать адрес, но нужно понять, что это неотъемлемая концепция программирования Nogeng. Она очень полезно, она очень сильно облегчает жизнь. Повторюсь,

476:02

Speaker C

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

476:22

Speaker C

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

476:39

Speaker C

всегда сможем иметь доступ к этому огроменному объекту просто разменованием. Либо второе очень важное применение указателей - это когда нам просто необходимо в разных точках программы работать с одним и тем же объектом в памяти. Не копировать его, а именно работать с одним и тем же.

477:01

Speaker C

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

477:13

Speaker C

Работаем с разными подключениями. По сути, если мы подключение скопируем, это уже будет другое подключение, а нам нужно работать именно с исходным.

477:23

Speaker C

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

477:39

Speaker C

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

477:54

Speaker C

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

478:13

Speaker C

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

478:29

Speaker C

переменной не важен в плане синтаксиса. Что написать? Там амперсант или звёздочка. Вот, допустим, у нас будет функция, которая будет изменять имя.

478:37

Speaker C

Change name. Принимать она будет указательно строку. Вот наша функция change name. Всё, что эта функция будет делать, она будет разыменовывать указатель S. То есть по указателю S будет идти к исходному объекту в памяти, к исходной строке и менять её значение.

478:57

Speaker C

Ну, наподобие того, как мы это делали вот в двадцать четвёртой строчке. И будет в эту переменную S класть и в мейне. Я всё сотру и создам переменную name. В неё положу имя Игорь. Потом создам указатель на переменный, ну,

479:12

Speaker C

назову его сокращённым PTR. То есть PTR - это сокращение от поинтера, поинте - это с английского указатель. То есть, по сути, когда я пишу PTR- это значит, что указатель P и возьму указатель на переменную namй. То есть всё, теперь у

479:26

Speaker C

меня в поинтере, в ПТРе, в переменной ПТР лежит указатель на name, то есть я в седьмой строчке просто взял, да, и создал очередной указатель на нашу переменную, которая вот лежит в памяти.

479:39

Speaker C

Вот просто создал очередной указатель. А на какую именно переменную я создал указатель, можно понять справа от знака присваивания на переменную name. Потом я напишу имя до изменения. Потом передам наш указатель функцию change name и напишу имя после изменения.

480:01

Speaker C

То есть, по сути, я до вызова change name и после вывожу значение переменной name. Если присмотреться, то напрямую мы нигде это с вами имя не меняем. Именно переменную name мы нигде никак не трогаем. Ну, давайте запустим нашу программу и увидим имя до изменения

480:21

Speaker C

Игорь, имя после изменения Иван. То есть наша переменна name поменялась. Почему она поменялась? Давайте сейчас рассмотрим. Вот мы в шестой строке просто создали обычную строковую переменную и положили в неё значение Игорь. Соответственно, вот мы создали нашу переменную, вот её имя, name, и

480:41

Speaker C

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

480:56

Speaker C

name, в которой лежит Игорь. Ну, соответственно, идём дальше. После этого мы создаём указатель на переменную name.

481:03

Speaker C

Ну, хорошо, указатели, концепция нам уже плюс-минус знакомая. Мы создаём указатель, и он указывает на нашу переменную name. После этого мы выводим имя до изменения. Ну, у нас просто создана переменная, создан на неё указатель, и мы выводим вот имя до

481:20

Speaker C

изменения. Там сейчас лежит Игорь. Вот, собственно, Игорь. Потом мы вызываем функцию change name, которая принимает указатель. Соответственно, в момент вызова функции, когда мы передали в неё указатель, этот самый указатель скопировался. Вот наш скопированный указатель, но он указывает на ту же

481:39

Speaker C

самую ячейку в памяти, на ту же самую область памяти. Мы как бы указатель скопировали, но адрес, который в нём лежит, остался тем же самым. Адрес переменной name, где лежит Игорь. Потом функции change name этот скопированный указатель разыменовывается, то есть доходит до

481:57

Speaker C

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

482:15

Speaker C

То есть взяли, да, и положили Иван. Вот так вот. Теперь тут лежит Иван. Всё, функция завершилась. Мы выводим имя после изменения. А тут уже Иван лежит. Почему?

482:28

Speaker C

Да потому что мы в самом начале создали переменную name, создали на неё указатель, потом передали этот указатель в функцию, он скопировался, и с помощью скопированного указателя мы разменованием дошли до исходной переменной, поменяли в ней значение. И потом мы, когда уже на экран снова

482:48

Speaker C

выводили name, мы уже увидели, что там лежит другое значение. Сейчас, наверное, единственное, что может быть прямо максимально непонятно, это почему же указатель у нас копируется. То есть почему мы, когда передаём функцию указатель PTR, почему не передаётся вот этот же самый указатель? Ну потому что

483:05

Speaker C

мы всё, что передаём в функцию, оно копируется. В Голенге нету у нас механизмов, чтобы передавать что-то напрямую. Мы всегда передаём копию.

483:15

Speaker C

Неважно, будь то переменная или указатель. То есть мы всегда передаём копию. Что это значит? Это значит, что мы внутри чейннейма могли бы в переменную S положить указатель на какую-нибудь другую строку. Тут бы мы создали новую строку какую-нибудь. Я бы

483:31

Speaker C

положил в неё что-нибудь hello. И потом мы бы этой самой переменной S присвоили указатель на str. То есть, что это значит? что мы, когда вызвали функцию change name, мы скопировали указатель, он вот здесь вот ещё до начала выполнения функции указывал бы на

483:49

Speaker C

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

484:04

Speaker C

другую переменную, назвали её STR и заставили этот указатель указывать уже на неё. Соответственно, у нас уже потерялся доступ к вот этой вот переменной исходной через скопированный указатель, потому что мы нигде не запомнили вот этот вот адрес памяти. И теперь на

484:22

Speaker C

исходную переменну у нас указывает только указатель, который мы первым создали в мейне. А вот этот вот наш указатель S мы заставили указывать на вообще созданную прямо внутри функции переменную str. То есть вот создали переменную и сразу же на неё завели

484:37

Speaker C

указатель. просто заставили вот этот S указывать с изначального нейма новую переменную. Вот таким образом работает язык программирования, в частности goeng. Когда мы что-то передаём в функцию, оно копируется. С указателями мы с вами будем очень часто сталкиваться. Это очень важная тема,

484:57

Speaker C

поэтому советую её как можно скорее и как можно лучше закрепить на практике. Но пока ещё мы прямо хорошо так плотно не работали с указателями, потому что просто не было необходимости. Мы ещё не сталкивались с какими-то там огромными переменными в памяти, и мы ещё не

485:14

Speaker C

сталкивались с такими объектами, которые нужно использовать во всех местах программы в единственном экземпляре. Ну, тот же самый conneнеction, то же самое подключение к базе данных. Мы пока ещё с этим не сталкивались, но концепцию указателей уже необходимо выучить, потому что дальнейшие темы будут

485:31

Speaker C

предполагать то, что с концепцией указателей мы с вами ознакомились. Раз уж мы с вами начали говорить про указатели, то хорошо бы нам рассмотреть такое понятие, как NILл указатели. Что такое указатели? Ну, если чисто технически говорить, то ни указатель -

485:48

Speaker C

это указатель, который у нас указывает в никуда, то есть никуда не указывает. Если указатель никуда не указывает, это nл указатель. Как это может выглядеть в коде? Допустим, у нас есть переменная number, в ней у нас лежит 15. И я хочу

486:03

Speaker C

на эту переменную number создать указатель. Ну, вроде всё довольно просто. То есть объявили переменную, переменную number и создали вот указатель на эту переменную. Вот он наш указатель pт. О'кей. А как нам сделать указатель, который указывает никуда? Для этого нам необходимо воспользоваться

486:20

Speaker C

длинной записью создания переменных. Я пишу ключевое слово. После этого название переменной, то есть PТR. После этого тип переменной указательно int. Ну и после этого я могу положить туда указатель на number. И в принципе будет то же самое, что и с короткой записью.

486:37

Speaker C

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

486:53

Speaker C

Ну вот наши number выведем на экран и указатель. Сохраняю и запускаю. Вот numberр у нас 15, а указатель. Что это значит? Это значит, что мы создали указатель, ничего в него не положили, указатель принял значение по умолчанию. А значение по умолчанию

487:14

Speaker C

для указателя - это нил. А нил значит, что он указывает в никуда. Что будет, если мы попытаемся разменовать нил указатель? То есть у нас указатель указывает в никуда, а мы попытаемся его разыменовать, то есть получить значение, на которое он указывает. Давайте

487:30

Speaker C

посмотрим что будет. [аплодисменты] Разменование. Ну, запускаем нашу программу и видим, что у нас фатальная ошибка. нам пишет, что мы в двенадцатой строчке попытались разыменовать NILл указатель. Почему это приводит к ошибке?

487:52

Speaker C

Да потому что указатель у нас никуда не указывает, а мы пытаемся получить какое-то значение, куда он указывает, а он указывает в никуда. Поэтому мы ловим фатальную ошибку. Поэтому обычно перед тем, как указатель разыменовывать, ставится проверка, что если указатель не

488:07

Speaker C

равен, и вот только если указатель не равен, тогда обычно производят разменовывание. Иначе, если указатель всё-таки равен, тогда обычно ничего не делается, либо там куда-нибудь в логи или на экран выводится, что получен указатель. Теперь запустим программу и увидим, что у нас поинтер

488:30

Speaker C

нашл. У нас проверка не прошла, то есть указатель нет, указатель. И мы вывели, что указатель. А если мы в указатель положим какое-то значение, начнём указывать с пустоты на переменную numberр, тогда увидим, что и указатель начал указывать на какую-то

488:51

Speaker C

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

489:09

Speaker C

информацию по сети или достаём какую-то информацию из базы данных. А у нас оказывается, что каких-то данных не хватает. И как раз-таки, если мы каких-то данных не дополучили, то у нас обычно приходят указатели, которые указывают в никуда. Соответственно, мы

489:28

Speaker C

должны в наших программах учитывать то, что указатели в теории могут прийти нам не которые куда-то указывают на какую-то переменную, а прийти указатели, которые, которые указывают в никуда. И поэтому перед тем, как вот разыменовывать указатель, нужно ставить проверки на то,

489:45

Speaker C

что указатель нел. Потому что если мы разыменуем нилказатель случайно, как вот в нашем примере у нас указатель указывает в никуда, мы пытаемся его разыменовать и получаем критическую ошибку. Вот, чтобы такого не было, обычно ставятся проверки на NILЛ указатель. Ну, я надеюсь, что какое-то

490:03

Speaker C

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

490:23

Speaker C

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

490:37

Speaker C

какую-то тему не поняли, обязательно нужно сделать всё, приложить все усилия, чтобы эту тему понять. Такие загуглить, спросить у неронки, спросить помощи в нашем приватном сообществе. Это очень важно. Нельзя забивать на какую-то тему и идти дальше. Хотя бы поверхностно, но

490:55

Speaker C

нужно её понять. На этой прекрасной ноте мы заканчиваем рассмотрение [музыка] указателей. Следующая тема на нашем рассмотрении - это структуры. Посмотрим, что такое структуры, для чего они вообще нужны, как их создавать, как их описывать, как с ними работать. Поехали.

491:14

Speaker C

Ну, сначала скажу совсем уж общие слова, что структура - это объединение каких-то переменных. Структура - это логическое объединение нескольких разных переменных, над которыми мы можем производить какие-то действия. То есть не как мы с вами раньше могли отдельно создать int, отдельно бул, отдельно

491:34

Speaker C

какую-нибудь другую переменную, а несколько переменных логически объединены в какую-то одну сущность, и мы над этой сущностью можем производить какие-то действия. Ну, это были совсем уж общие слова. Теперь давайте перейдём к конкретному примеру. Допустим, мы с вами разрабатываем социальную сеть, и мы

491:53

Speaker C

хотим в нашей программе уметь работать с пользователями этой социальной сети. То есть мы хотим уметь их сохранять в базу данных, мы хотим получать наших пользователей с базы данных, мы хотим в коде какие-то операции над пользователями производить. Как нам это

492:08

Speaker C

сделать? Мы можем взять несколько разных переменных и логически их объединить в одну сущность. Ну, допустим, у нас есть пользователь. Что может быть у пользователя? У него может быть имя. Имя мы бы сделали типомстрин. Ну, пому что это строка какая-то. У пользователя

492:24

Speaker C

может быть возраст. Ну, возраст - это инт, то есть какое-то целое число. У пользователя может быть номер телефона.

492:30

Speaker C

Ну, это мы можем, в принципе, строкой тоже представить. У пользователя может быть информация о том, закрыт ли у него аккаунт, либо открыт. Это, напоминаю, тип данных булин. То есть либо да, либо нет, либо закрыт, либо открыт. И у

492:43

Speaker C

пользователя может быть рейтинг. Ну, какой-нибудь рейтинг там в социальной сети. Допустим, пользователь сделал какое-то социально одобряемое действие, у него вырос рейтинг. Пользователь сделал что-то плохое, у него этот рейтинг упал. Ну, рейтинг у нас пускай будет дробным от нуля до десяти, то есть

492:57

Speaker C

он может быть 5 12, может быть 7.2. Вот рейтинг типа флот. То есть флот - это как бы дробь. Соответственно, эти все переменные, они в сумме образуют пользователя. Мы могли бы каждую из этих переменных создавать отдельно и пытаться

493:11

Speaker C

как-то с ними работать, но это неудобно. Гораздо удобнее. их логически объединить в одну структуру, в одну сущность, назвать эту сущность пользователь и потом работать с этой сущностью. Также мы можем отдельно прописывать то, что именно наш пользователь умеет, что

493:28

Speaker C

именно мы с нашим пользователем можем делать. Это какие-то действия, которые мы бы могли делать с нашим пользователем. То есть, к примеру, у нас есть информация о том, закрыт ли аккаунт или открыт. И мы можем либо закрывать аккаунт пользователю, либо открывать. То

493:44

Speaker C

есть пользователь там где-то у себя на страничке нажал кнопочку, что я хочу закрыть аккаунт. Мы эту информацию получили и закрыли аккаунт пользователю.

493:52

Speaker C

По сути, просто поменяли вот эту вот переменную. Она у нас была false, то есть закрыт ли аккаунт. Fse, то есть было открыто. А когда мы закрыли аккаунт, он стал true. То есть мы закрыли всё-таки аккаунт. Ну, когда мы

494:06

Speaker C

открываем аккаунт, мы опять делаем это флS. Потом поднять рейтинг - это, по сути, вот эту вот переменную flatт увеличить на сколько-то единиц. Понизить рейтинг - это вот эту переменную флоат уменьшить на несколько единиц. Ну и поменять номер телефона - это, по сути,

494:20

Speaker C

просто поменять вот эту вот строчку, поставить туда какой-нибудь другой номер телефона. Так вот, это наша структура.

494:27

Speaker C

Структура - это логически объединённые переменные под одной какой-то сущностью. В данном случае мы объединили переменный рейтинг, закрыт ли аккаунт, номер телефона, возраст и имя под логической сущностью usюзеer. То есть usеer - это у нас структура. Каждая вот эта отдельная

494:45

Speaker C

переменная, она называется полем структуры. То есть возраст - это поле структуры, имя - это поле структуры usеer. Закрытый ли аккаунт - это поле структуры usеer. Рейтинг - это поле структуры usеer. Это поля. А действия, которые мы описываем, которые мы можем

495:00

Speaker C

делать с этой структурой - это методы. Ну, в общем-то, с терминологии разобрались. Теперь давайте перейдём к написанию кода и посмотрим, как это вообще выглядит в программе. Вот у нас main. Файл. В нём, по сути, пустая программа. Давайте теперь будем работать

495:18

Speaker C

с нашими структурами. Вот когда мы с вами раньше создавали переменные типа string, типа int, нам вот эти вот типы описывать не нужно было. То есть тип string - это встроенный в язык программирования тип. Тип int - это тоже

495:34

Speaker C

встроенный в язык программирования тип. Поэтому нам не нужно было описывать, что из себя представляет strтринг. Мы могли сразу создать переменную типа strст string. Но когда мы хотим создать переменные каких-то наших кастомных типов, наших кастомных структур, нам нужно сначала описать, что вообще такое

495:54

Speaker C

usеer. То есть язык программирования изначально не знает, какое представление юзера в нашей программе. Язык программирования знает, что такоестрин, что такое int, а что такое usер, язык программирования не знает. Поэтому нужно ему сначала объяснить, как с нашей точки зрения выглядит usеer. Описание

496:13

Speaker C

структуры имеет следующий синтаксис. Пишем type user strctct. Что это значит? Это значит, что сейчас в этих скобочках будет описание структуры usеer. Ну и ключевое слово type продиктовано синтаксисом. Его просто необходимо написать. То есть это значит, что сейчас мы будем описывать структуру usеer. Ну

496:35

Speaker C

смотрим. Первое, что у нас есть в структуре user - это имя типа string. Имя с английского name типа string.

496:43

Speaker C

Таким образом, мы сказали, что у нас есть структура user, и в этой структуре usеer есть имя типа string, что у нашего юзера есть имя. После этого у нас возраст, возраст с английского age, типа int. Теперь мы с вами сказали, что у нас

496:57

Speaker C

есть usеer. У этого юзера есть имя и возраст. Ну и так дальше. Номер телефона. Phone number string. Закрыты ли аккаунт? Я напишу is close, типа були и рейтинг типа flat. Ну, flat 3264 и то, и то - это дробное число, но просто flat 64

497:17

Speaker C

будет занимать у нас 8 байт, а флот 32 у нас будет занимать 4 байта, но Flot 32 гораздо меньше точности имеет. Сейчас уже практически везде используется Flot 64. И в Flot 32 практически никогда нет необходимости. Поэтому выбираю Flot 64.

497:34

Speaker C

Таким образом, мы с вами описали, что такое, с нашей точки зрения usеer. Тут мы ещё ничего не создали, то есть это не создание переменной, это просто описание того, что с нашей точки зрения является юзером. Это просто описание. А если мы

497:52

Speaker C

напишем вот так, то это мы уже создадим нашего пользователя. То есть тут это просто описание, описание структуры.

498:02

Speaker C

А тут мы уже создали конкретный экземпляр. Ну давайте выведем его на экран. Сохраняю, запускаю. И, как мы видим, вывелась какая-то странная фигня. Что тут произошло? Когда мы с вами создаём структуру, мы, вообще-то говоря, можем при создании ей указывать, какие значения полей должны

498:27

Speaker C

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

498:46

Speaker C

Значение по умолчанию для булина - это фолs и значение по умолчанию для flot 64 - это тоже ноль. Соответственно, мы не указали никакое из этих полей при создании. Таким образом, каждому полю присвоилось значение по умолчанию. То есть мы имени присвоили пустую строку.

499:03

Speaker C

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

499:18

Speaker C

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

499:35

Speaker C

двоеточие указать значение, которое мы хотим этому полю присвоить. Ну, имя я хочу поставить Сергей. Возраст я хочу поставить 64. Номер телефона я хочу поставить там +7 911 911, там 11 22. Ну вот для красоты можно вот так вот это указать.

499:56

Speaker C

Вот номер телефона из close. Можно указать, можно не указать. Любое поле мы можем указывать, а можем не указывать на своё усмотрение. Мы, как программисты, должны понимать, что при создании нам необходимо указать, а что можно опустить. Также это зависит от конкретно

500:14

Speaker C

решаемой задачи. Но пока мы не решаем какую-то конкретную задачу, мы просто рассматриваем то, как вообще у нас происходит работа со структурами.

500:22

Speaker C

Поэтому давайте укажем каждое поле. Из close я напишу true, то есть закрытый аккаунт изначально. И рейтинг я поставлю, ну, пускай будет 5. Теперь выведем на экран нашего пользователя.

500:35

Speaker C

Вуаля. Каждое поле, которое мы задали, теперь начало иметь какое-то значение. Структура у нас выводится сверху вниз.

500:43

Speaker C

Имя, Сергей, возраст 64, номер телефона, закрытый ли аккаунт, true, то есть закрытый, и рейтинг. то, что мы и задали. То есть мы при создании структуры можем каждому полю задавать сразу же какое-то значение, и оно будет сохранено в поле этой структуры. Можем

501:02

Speaker C

что-то не указывать. Допустим, мы не укажем возраст. В таком случае у нас возраст примет значение по умолчанию, станет ноль. Ну, мы хотим указать возраст, поэтому пускай оставим. Также мы можем выводить на экран не целую структуру, можем выводить на экран только отдельные

501:19

Speaker C

её поля. Ну, допустим, мы хотим вывести только имя. Имя. Для этого нам нужно написать саму структуру. И через точку мы получим доступ ко всем её полям. То есть мы пишем название нашей переменной, в которой лежит структура, точка. И сразу редактор кода нам

501:39

Speaker C

подсказывает, что мы из этой структуры можем достать. Возраст, закрыт ли аккаунт, имя, номер телефона, рейтинг.

501:44

Speaker C

Ну, мы хотим вывести имя, поэтому я выбираю имя. Сохраняю, запускаю. И как мы видим, отдельно вывелось только имя, потому что мы получили к нему доступ. Таким же образом, мы можем менять поля прямо по ходу работы программы. То есть я выведу имя до,

502:04

Speaker C

потом я это имя поменяю. Выглядит это следующим образом. Пускай у нас теперь имя будет Игорь. И выведу имя после.

502:17

Speaker C

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

502:38

Speaker C

одна проблема, когда мы работаем с полями следующим образом. Допустим, мы вот описали нашу с вами структуру. Мы знаем, что у нас рейтинг должен быть с нуля до 10. И отдаём эту самую структуру нашим коллегамразработчикам, которые уже потом будут с ней работать. Наши

502:58

Speaker C

коллеги-разработчики, они забыли, что рейтинг должен быть от нуля до 10. Взяли, создали юзера и присвоили ему рейтинг 555. Запускаем программу, видим, что да, действительно. Рейтинг у нас стал 55, но это против наших правил. Это, в принципе, может сломать логику

503:18

Speaker C

выполнения программы, потому что мы завязались на то, что у нас рейтинг от нуля до 10, а кто-то взял и поставил туда 555, потому что у него был полный доступ ко всем этим полям, и он не знает, как правильно менять рейтинг. На

503:31

Speaker C

такие случаи у нас есть механизм, который называется методы. Чтобы рассмотреть методы, мы перейдём к более простому примеру. Опишем также юзера.

503:42

Speaker C

Type user, только у него будет имя и у него будет рейтинг. Упрощённая структура юзера, у которой есть только имя и рейтинг.

503:52

Speaker C

Давайте создадим нашего юзера. Напомню, здесь это просто описание того, как с нашей точки зрения должен выглядеть юзер. А в девятой строчке мы уже прямо создаём конкретный экземпляр по этому описанию. Ну, зададим ему имя, Вася и рейтинг. Пускай у него

504:10

Speaker C

будет 6,0. Ну давайте опять же выведем на экран, посмотрим, что у нас всё верно [аплодисменты] создалось. Да, usеer Вася рейтинг 6.

504:20

Speaker C

Сейчас будут примеры методов, которые демонстрируют то, как эти методы работают, но по своей сути они могут быть в каком-то плане бесполезны, потому что так повелось, что простые примеры, они по своей сути бесполезны, зато показывают с технической точки зрения,

504:36

Speaker C

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

504:50

Speaker C

зовут Вася, у меня такой-то рейтинг". Ну давайте это и сделаем. Опишем функцию, назовём её, и эта функция будет принимать юзера. То есть функция, она принимает юзера и выводит на экран. Всем привет.

505:03

Speaker C

[аплодисменты] Меня зовут. И сюда мы будем передавать имя пользователя. То есть меня зовут, а здесь мы будем получать имя пользователя. Таким образом у нас будет меня зовут там Вася, меня зовут Петя, в зависимости от того, что лежит в поле

505:24

Speaker C

структуры. Мой рейтинг. И здесь через запятую тоже usеррейтинг. Всё, таким образом мы будем писать. Всем привет. Меня зовут Так-то, так-то. Мой рейтинг такой-то, такой-то.

505:36

Speaker C

Ну и в конце пустую строчку выведу просто для красоты, чтобы выводы наши разделялись. Давайте проверим, как это работает. Я вызову функцию Greating, передам туда usеer, запускаю программу.

505:45

Speaker C

Всем привет, меня зовут Вася. Мой рейтинг. То есть мы создали какую-то переменную, мы передали её в функцию не по указателю, а просто как копию, да?

505:55

Speaker C

Повторюсь, вот здесь вот мы просто создали какую-то переменную в памяти. То есть структура - это тоже какая-то переменная. То есть, когда мы создаём структуру, мы тоже создаём какую-то переменную, тоже выделяем какую-то область в памяти. Вот, допустим, вот это

506:09

Speaker C

вот наша оранжевая структура. Можно воспринимать структуру как обычную переменную. Это тоже какая-то область в памяти, которая выделяется, которая под собой просто содержит ещё дополнительные поля, но по сути своей это переменная.

506:22

Speaker C

Мы передаём эту переменную функцию. То есть здесь, я напоминаю, будет происходить копирование. То есть наша переменная, которая в мейне создаётся, она копируется и передаётся в функцию. И уже внутри функции мы работаем именно с копией. Что это значит? Что если мы

506:39

Speaker C

внутри функции захотим, например, поменять рейтинг равно 3, допустим, то это никакого влияния не окажет на нашего пользователя, который в мейне. Давайте я буду выводить usеer [аплодисменты] до июзер после.

507:00

Speaker C

Здесь ещё пустую строчку добавлю. Запускаю программу и вижу до Вася 6 и юзер после Вася 6. Хотя тут мы вроде бы поменяли ему рейтинг, но на самом деле мы этот рейтинг поменяли у копии. Когда мы передали какую-то переменную по значению, то есть тут нет

507:20

Speaker C

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

507:34

Speaker C

функция гритинг. Она принимает юзера и выводит на экран нашего пользователя, выводит его приветствие. Всем привет.

507:40

Speaker C

Меня зовут Вася рейтинг 6. А теперь представим, что у нас помимо приветствия есть ещё возможность прощаться. Назовём эту функцию Goodbye. Она тоже принимает юзера и выводит. Всем пока. Меня звали так-то. Мой рейтинг был. И через запятую тоже рейтинг

508:08

Speaker C

выведим такой-то. Я опять же пустую строчку в конце выведу для разделения. Ну давайте посмотрим. Вот у нас есть, потом goodbyй и тоже передаём юзера.

508:19

Speaker C

Запускаем программу и видим, что у нас как бы юзер не поменялся. Ну, потому что мы его даже не меняем нигде. А если бы меняли, то он не поменялся, потому что тут копия, тут ещё одна копия создавалась. Вот у нас есть usер до,

508:32

Speaker C

юзер после. И смотрим. Всем привет. Меня зовут Так, там мой рейтинг такой-то. И goodbyй.

508:39

Speaker C

Всем пока. Меня звали Так, там мой рейтинг был такой-то. Ну, вроде всё хорошо, но тут есть одна проблема.

508:46

Speaker C

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

508:57

Speaker C

Также представим, что у нас не один файл в программе, а много файлов в программе.

509:01

Speaker C

Мы с вами в будущем научимся создавать много файлов в программе. И тогда уже становится проблематично узнать, что же именно наш пользователь умеет. Когда у нас один файл, мы, в принципе, можем посмотреть, а он умеет кидать приветствие и умеет прощаться. Хорошо.

509:16

Speaker C

Но если у нас файлов становится много, если у нас этих функций, которые как-то работают с юзером, становится много, то мы начинаем путаться. Мы начинаем забывать, что именно наш юзер умеет, нам приходится долго это искать, это становится очень неудобно. И вот бы была

509:31

Speaker C

такая возможность, сразу смотря на структуру, сразу смотря на переменную в коде, понимать, что именно она умеет.

509:39

Speaker C

Без необходимости просматривать огромные файлы, без необходимости просматривать все функции. Вот бы была такая возможность. А такая возможность есть.

509:49

Speaker C

Мы можем сказать, что эта функция у нас относится конкретно к структуре usеer и потом по структуре usеer сразу понимать, какие функции к ней относятся. Как это сделать? Всё довольно просто. Мы вот этот вот аргумент, который у нас здесь в

510:03

Speaker C

скобочках, мы выносим его в другие скобочки. И теперь, ну, логика не изменилась, всё то же самое, но теперь мы вызывать приветствие можем прямиком из переменной usеer. Как это выглядит?

510:18

Speaker C

Мы пишем usеer точка. И теперь нам подсвечивается, что нам доступна функция гритинг, которая относится к пользователю. Вот такая вот функция, которая существует не просто как функция, а которая относится к конкретной структуре, называется метод.

510:34

Speaker C

Теперь гритинг - это метод структуры usеer. Как мы поняли, что именно структура usеer? По вот этим вот скобочкам, которые между ключевым словом фунто. Теперь это метод структуры usеer.

510:47

Speaker C

Логика осталась той же, ничего не изменилось. По сути, вот это обычная функция. И вот это с точки зрения логики выполнения программы, это одно и то же. Это просто синтаксический сахар для обычной функции. Метод - это синтаксический сахар для обычной

511:07

Speaker C

функции. Но что он нам даёт? Он нам даёт возможность узнать, что именно относится к какой-то конкретной структуре. Мы можем поставить точку и увидеть, что у нас есть метод гритинг. Это очень удобно. То есть, если бы мы оставили это

511:22

Speaker C

всё в плане функции, как у нас это было до этого, вот как обычная функция, то нам бы никакой этой информации не было доступно. Мы бы ставили точку, видели только поля нашей структуры, никаких методов. Нам бы пришлось в коде

511:36

Speaker C

выискивать все вот эти функции, которые там принимают юзера и смотреть, что они делают. А если мы это делаем методом, то нам это сразу всё становится доступно.

511:45

Speaker C

Ну давайте Goodbyй тоже сделаем методом. Теперь мы, когда будем писать usеer, ставить точку, нам помимо полей структуры сразу же будут доступны её методы. Мы сразу же, благодаря одной точке, сможем узнать, что именно умеет наша структура. А наша структура умеет

512:01

Speaker C

делать goodbyй и умеет делать гритинг. Ну давайте сделаем сначала гритинг, а потом goodbyй. Запустим нашу программу и увидим, что работает она точно так же.

512:10

Speaker C

Всем привет, меня зовут Вася. Всем пока. Меня звали Вася. Почему нам до этого требовалось передавать юзера аргументом, а теперь не требуется? Да потому что когда мы вызываем метод от конкретного юзера, то язык программирования сразу понимает, к какому конкретно юзеру

512:24

Speaker C

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

512:42

Speaker C

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

512:57

Speaker C

и выбрать нужное нам действие. И этот вот юзер, эта переменная, она сама сюда автоматически передастся, и мы сможем иметь к ней доступ изнутри и также получать его имя и рейтинг. Казалось бы, всё замечательно, но теперь представим, что мы хотим сделать метод, который бы

513:17

Speaker C

наш рейтинг позволял менять. Ну, допустим, у нас есть метод юзера, он будет называться рейтинг и принимать какой-то рейтинг, на который мы хотим увеличить. Ну вот флот 64. И что он будет делать? Он будет, во-первых, смотреть, что рейтинг юзера

513:35

Speaker C

плюс рейтинг, который мы хотим добавить, они меньше либо равны десяти. Для чего? Для того, чтобы у нас не случилась ситуация, когда мы добавляем рейтинг, и он становится больше десяти, хотя это мы уже обсуждали невалидно. Ну, в рамках нашей программы просто мы вот так вот

513:51

Speaker C

решили. Ну и, соответственно, мы берём и проверяем, что если у нас после добавки рейтинга в итоге будет меньше либо равно 10ти, то есть мы после добавки останемся в рамках валидных значений, то мы берём и [аплодисменты] добавляем. Напоминаю, плюс равно - это

514:08

Speaker C

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

514:21

Speaker C

Я добавил рейтинг. Иначе, то есть, если мы не прошли валидацию, а это по сути валидация, то есть мы уже добавляем в наши методы какую-то валидацию, тогда я буду выводить, если валидацию не прошёл.

514:33

Speaker C

Я не прошёл валидацию. И давайте посмотрим, что же будет с нашей структурой. Вот наш рейтинг до 60. Я беру и у нашей структуры user вызываю метод rating up и передаю туда рейтинг, на который я хочу повысить. Ну, допустим, я хочу на 5.0 повысить.

514:50

Speaker C

Смотрим, что у нас будет. Я у переменной usеer вызываю метод rating up. Вот он у нас изначально рейтинг 6.0. Вот он тут 6,0. Я хочу ещё 5.0 прибавить. Ну 6,0 + 5,0 - это 11,0. Вот эта проверка не

515:04

Speaker C

пройдёт, поэтому выведется. Я не прошёл валидацию. Давайте запустим. Я не прошёл валидацию. И всё.

515:12

Speaker C

И у нас рейтинг до был шесть. Так и он после и остался. Рейтинг шесть. Ну, потому что мы не прошли валидацию. А теперь давайте поставим сюда рейтинг 2.

515:21

Speaker C

По сути 6 + 2 - это 8. 8 меньше 10, поэтому должно быть выведено. Я добавил рейтинг, и наш рейтинг должен добавиться. Ну, запускаем программу.

515:32

Speaker C

Рейтинг до шесть. Я добавил рейтинг. Рейтинг после тоже шесть. Почему? Давайте разбираться, почему у нас не изменился наш рейтинг. Хотя мы вроде бы как его добавили и написали: "Я добавил рейтинг". Вспоминаем, что я говорил, что вот эта запись - это по сути своей то же

515:51

Speaker C

самое, что и обычная функция, просто добавляет нам удобств, что мы знаем, что это относится к нашей структуре usеer. Мы сразу же можем иметь доступ к этому методу, имея просто структуру. Это просто синтаксический сахар для вот этого метод - это просто

516:10

Speaker C

синтаксический сахар для структуры. Вот это и это то же самое. Давайте я метод закомментирую, оставлю только функцию.

516:18

Speaker C

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

516:32

Speaker C

передаём в качестве аргументов функцию. Мы, если не используем никаких указателей, а просто передаём переменную функцию, то эта переменная копируется.

516:45

Speaker C

Соответственно, мы, передав юзера функцию, создали копию. И внутри этой функции мы рейтинг прибавили к копии. То есть мы поменяли вот эту вот копию, но исходного юзера, который у нас был в мейне, мы не поменяли. Он как был в

517:02

Speaker C

мейне, так и остался. Поэтому у нас изменения на копии, они никак не отразились на основной структуре. Что мы можем с этим сделать? Ну, мы можем создать указатель на нашего юзера.

517:15

Speaker C

Создаём указатель. Он будет указывать на юзера. Вот он указывает. Создаём этот самый указатель. Потом внутри функции будем ждать не копию, а будем ждать указатель.

517:26

Speaker C

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

517:39

Speaker C

Соответственно, здесь мы уже имеем указатель, но указывает он на исходную нашу структуру. Соответственно, мы через этот указатель уже сможем поменять исходный объект. Язык программирования Goeng нам в этом помогает. Нам даже тут ничего не нужно разыменовывать, потому что когда мы работаем со структурами,

518:00

Speaker C

когда мы работаем с указателями на структуры, язык программирования автоматически разыменовывает эти самые указатели, и мы получаем доступ к полям и методам структуры, на которую у нас есть указатель. То есть есть у нас указатель на структуру usеer. Мы можем

518:14

Speaker C

сразу же применить к ней либо метод какой-то, либо через точку там получить доступ к нашим полям. Соответственно, вот мы через точку получаем доступ к полюйтинг и прибавляем к нему наше значение. Мы с помощью переданного, скопированного указателя имеем доступ к

518:32

Speaker C

нашей исходной структуре. И мы благодаря следующему синтаксису у исходной структуры через указатель меняем рейтинг. Давайте посмотрим, что теперь у нас будет. У нас есть изначальная структура usзееer. Создаём на неё указатель, передаём этот указатель в функцию и выводим usюзеer до, usзеер

518:49

Speaker C

после. Ну, запускаем нашу программу. И, как мы видим, usер до у нас имел рейтинг 6, user после рейтинг восемь. То есть мы взяли и прибавили двоечку. Вот здесь вот прибавили двоечку, после чего изменился рейтинг у нашей оригинальной структуры.

519:05

Speaker C

Хорошо, это всё круто. То есть мы можем передавать наши структуры по указателю и менять к ним рейтинг. То есть мы даже можем посмотреть, что если мы передали какой-то невалидный рейтинг, то нам скажут, что мы не прошли валидацию. А

519:18

Speaker C

если мы передадим валидный рейтинг, например, 3.25, то у нас всё отлично будет выполнено. Нам скажут, что мы добавили рейтинг, и мы увидим изменения. Всё круто. Но я бы хотел, чтобы это всё-таки было не функцией, а это было методом,

519:35

Speaker C

как у нас до этого. Потому что методы - это удобно. Мы бы могли просто писать user. Передавать тударейтинг, и всё было бы классно. То есть мне бы опять не пришлось пользоваться функциями. Мне пришлось бы помнить, что у меня где-то

519:50

Speaker C

там в каком-то файле какая-то функция лежит, она что-то там принимает указатель на юзера и так далее. Как это можно сделать методом? Ведь мы помним, что в методе у нас принимается копия.

520:00

Speaker C

Изменения копии у нас не влияют на исходный объект. Да, всё просто. Мы точно также берём вот этот вот первый аргумент юзера, вырезаем отсюда и выносим за скобки. Всё. Теперь это метод структуры usеer. Но в этом методе структура usеer

520:21

Speaker C

будет использоваться не копией, как у нас было до этого, а по указателю. Всё. Теперь мы можем удалить ручное создание указателя, удалить вызов функции и просто писать user тоrat ratingup и передавать туда рейтинг, на который мы хотим прибавить наше значение. Запускаем

520:41

Speaker C

программу. Всё, я добавил рейтинг. И как мы видим, к шести добавилось полтора, получилось 72. Всё. Теперь мы можем прописывать методы, которые будут менять ту структуру, от которой мы их вызываем.

520:53

Speaker C

Если говорить умными словами, то вот эта вот структурка, которая у нас в скобочках, да, вот этот вот аргумент, который мы вынесли отсюда в скобке, называется ресивер. Ресивер у нас может быть по значению, когда у нас создаётся копия. И

521:13

Speaker C

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

521:32

Speaker C

никак не изменит. Вот смотрим. Я добавил рейтинг, но рейтинг так и остался шесть. А если у нас ресивер по указателю, то у нас изменится именно наш исходный объект. Мы через указатель получим к нему доступ. У этого исходного объекта

521:47

Speaker C

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

522:04

Speaker C

требуется как-то изменять исходную структуру, как, например, в методах и goodby, то нам можно использовать ресивер копией. Если же нам нужно как-то менять внутри метода нашу структуру исходную, тогда используем ресивер по указателю. У этой темы есть ещё несколько подводных нюансов, когда

522:21

Speaker C

всё-таки лучше использовать указатель, когда лучше не использовать. Но на первых порах руководствуйтесь логикой, что если я хочу внутри нашего метода поменять исходную структуру, тогда я буду использовать ресивер по указателю, иначе я буду использовать ресивер копии.

522:37

Speaker C

Таким образом, мы создали структуру юзера. Мы создали ей методн и метод goodby и метод rating up. Ну, у меня тут опечаточка, что ещё раз показывает, что методы мы можем назвать как захотим.

522:50

Speaker C

Методы можем называть как захотим. Структуры можем называть как захотим. Переменные можем называть, как захотим, поля структур можем называть, как захотим. Но необходимо придерживаться всё-таки человеческой логики и называть наши структуры, поля структур, методы как-то осмысленно, чтобы потом не запутаться. То есть так мы сразу видим,

523:09

Speaker C

что у нас есть структура юзера, у юзера есть имя и рейтинг, и мы можем этот рейтинг поднять. А теперь представим, если бы у нас тут было А B C D, и мы бы ни хрена не поняли, что за А BC, что за

523:22

Speaker C

D. Поэтому нужно осмысленные названия давать всему, что мы можем создавать: структурам переменным методам всему нужно осмысленное название давать. При этом не нужно давать слишком длинные названия. Это тоже путает. Как можно короче, как можно более ёмко, как можно более понятно. Вот это наша задача как

523:40

Speaker C

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

523:58

Speaker C

того, чтобы случайно не поставить в неё что-то непонятное, например, рейтинг 555, да? Хотя у нас рейтинг должен быть от нуля до 10. Ну давайте зададим какие-то правила для каждого из полей.

524:08

Speaker C

Ну, имя у нас пускай будет вот это имя. пользователя. И правило, имя должно быть не пустое.

524:18

Speaker C

Хорошо. Это вот у нас для имени такое правило. Потом для возраста. Возраст пользователя. Правило: возраст должен быть больше нуля и меньше 150. Теперь номер телефона.

524:41

Speaker C

номер телефона. Правило, ну, пускай будет довольно простое правило, что номер телефона не должен быть пустым. Теперь у нас close.

524:52

Speaker C

Ну, то есть это закрыт ли профиль пользователя. [аплодисменты] По сути, тут какие-то правила мы можем не выставлять, потому что у нас тип данных буllет всего два значения. Либо true, либо false. И оба значения мы можем считать валидными, потому что

525:09

Speaker C

профиль либо закрыт, либо открыт. Что-то тут сломать, ну, я даже не представляю, возможно ли. Поэтому каких-то правил можем не задавать. И вот рейтинг - это рейтинг пользователя. Правило. То есть рейтинг мы уже можем сломать, да? Мы можем отрицательный рейтинг поставить, мы

525:26

Speaker C

можем поставить рейтинг миллион. Поэтому правило рейтинг должен быть больше либо равен нулю но меньше либо равен 10ти. Хорошо. Вот мы описали наши поля, мы описали правила, которым они должны соответствовать.

525:49

Speaker C

Давайте будем создавать методы, которые будут валидировать новые значения, которые мы хотим выставить в структуре на эти правила.

525:58

Speaker C

Ну, первым делом сделаем метод, который бы менял имя. То есть вот тут давайте у нас будет не только поменять номер телефона, но ещё и поменять имя. Можем поменять имя. Так как мы хотим менять поле структуры в методе, то

526:15

Speaker C

сивер я сделаю по указателю. Назову этот метод change name. И принимать он будет новое имя, которое мы хотим поставить. назову его new name, типа строки. И мы смотрим, что если у нас new name не равно пустой строке, то есть если у нас не пустая

526:36

Speaker C

строка, тогда мы в нашу исходную структуру будем переписывать имя. То есть в name будем класть new name. Всё. Вот наша валидация на то, что новое имя, которое мы ставим, оно не пустое. Если наше новое имя не пустое, тогда мы его перезапишем. Хорошо. Теперь

526:54

Speaker C

сделаем метод, который бы у нас менял возраст. То есть мы как поменять имя, теперь можем ещё и поменять возраст. Вот у нас возможность будет менять возраст.

527:05

Speaker C

Правило возраста: возраст должен быть больше нуля и меньше 150. Ну хорошо. Опять же, я буду менять поля исходной структуры, поэтому сивер по указателю. Change H. New H и буду смотреть, что если у меня new больше нуля и new age меньше 150,

527:28

Speaker C

тогда всё хорошо. То есть возраст должен быть больше нуля, меньше 150. То есть если это условие проходит, значит, мы прошли валидацию, и мы можем перезаписать наш возраст. То есть мы в поле Age структуры usеer положим новый возраст. Хорошо. Дальше у нас номер

527:42

Speaker C

телефона. Номер телефона не должен быть пустым. Ну, хорошо, давайте сделаем метод, опять же, ресивер по указателю, потому что я буду менять поле структуры. Change phone number, new phone number, типа string. Я буду смотреть просто, если new phone number у меня не пустой, тогда я

528:04

Speaker C

могу поменять его. Отлично. Дальше у меня is close. Но тут каких-то проверок нам не нужно. Нам, по сути, нужно просто предоставить возможность закрыть аккаунт и открыть аккаунт. Ну, мы бы могли это оставить на откуп нашим коллегам, которые бы писали

528:22

Speaker C

что-то вроде user is close = true, что значит закрыть аккаунт и user is close false, что значит открыть аккаунт. Но это может быть довольно неочевидно. К нам постоянно будут приходить, спрашивать: "А что значит закрыть аккаунт? А как мне

528:41

Speaker C

закрыть аккаунт?" Нам нужно говорить, вот тебе нужно переменную поменять. А, понятно. Лучше мы это тоже вынесем в отдельные методы. То есть вот закрыть аккаунт. Я назову метод close [аплодисменты] account. Close account. И этот наш метод будет закрывать аккаунт. Ну, у нас тут

529:00

Speaker C

usер называется. Указатель на usеer. Сохраняем. Всё. Вот наш метод, который закрывает аккаунт. Он просто ставит переменную из close в true. То же самое с открытием аккаунта. То есть открытие аккаунта usеer и он наш open [аплодисменты] account. Вот это значит открыть аккаунт.

529:21

Speaker C

Всё. Теперь каждый раз, когда кто-то будет использовать нашу структуру, он сможет просто написать название переменной, в которой эта структура лежит, поставить точку и увидеть, что а мы можем поменять имя, поменять возраст, поменять номер телефона, закрыть аккаунт, открыть аккаунт. И тем нашим

529:40

Speaker C

коллегам, кто будет использовать нашу структуру, уже не придётся вникать в подробности, а как именно закрыть аккаунт. У них просто будет метод close аккаунт, и они его могут вызвать, и они будут знать, что аккаунт закроется. А уже конкретная реализация этого метода,

529:54

Speaker C

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

530:14

Speaker C

от наших коллег мы скрываем конкретные детали реализации. Наших коллег уже не будут волновать конкретно детали реализации. Они просто смогут вызывать наши методы и быть спокойными, что они ничего не сломают. У нас тут инкапсулированы проверки, инкапсулирована валидация новых значений. Если наши коллеги захотят

530:38

Speaker C

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

530:52

Speaker C

открыть аккаунт. Хорошо. Дальше у нас остался рейтинг. Создадим метод, который бы поднимал рейтинг. Up, который бы у нас опускал рейтинг, то есть рейтинг [аплодисменты] да. Когда мы поднимаем рейтинг, нам нужно смотреть, что если бы мы подняли наш рейтинг, это бы не привело к тому, что

531:19

Speaker C

мы вышли за верхнюю границу разрешённых значений. То есть, если мы прибавим наш рейтинг и это не выйдет за верхнюю границу разрешённых значений, тогда мы, собственно, наш самый этот рейтинг можем прибавить. То же самое с уменьшением рейтинга. Мы должны посмотреть, что если

531:37

Speaker C

мы вычтем рейтинг, который мы хотим уменьшить, то это не приведёт к тому, что мы окажемся ниже нижней черты.

531:46

Speaker C

Соответственно, если мы уменьшим рейтинг, мы смотрим, что мы хотя бы в нуле останемся, либо будем больше. Если так, то можем спокойно наш с вами рейтинг уменьшать. Всё, мы написали структуру, мы написали к ней методы, и теперь вся работа со структурой у нас

532:01

Speaker C

будет сводиться к тому, что мы создаём структуру и можем вызывать какие-то методы. Ну вот, например, usеer. Давайте выведем рейтинг до, и я выведу рейтинг юзера нашего, а потом выведу рейтинг после. Userрейтинг. А между двумя этими выводами я подниму рейтинг нашему юзеру.

532:22

Speaker C

Я сделаю user rating up и подниму его на 2.4. Сохраняю и запускаю рейтинг до 5,5. Потом я прибавил 2,4, у нас стало 7,9. Если бы я захотел прибавить рейтинг на какое-то невалидное значение, например, на 100 с поно, то я увидел бы,

532:44

Speaker C

что мой рейтинг не изменился, потому что у нас не прошла проверка вот эта вот.

532:49

Speaker C

Также хочу сказать, что если мы хотим сразу же прыгнуть на реализацию этого метода, можно нажать, если вы на Линуксе или на винде, Ctrl и левую кнопку мыши.

532:58

Speaker C

Если вы на Маке, то Command и левую кнопку мыши. И таким образом вы прыгнете сразу же в реализацию этого метода.

533:04

Speaker C

Соответственно, мы можем увидеть, что у нас у структуры вызывается какой-то метод, сразу же прыгнуть в него и проверить, что тут вообще происходит.

533:12

Speaker C

Ну, в данном случае видим проверку нашу, из-за которой у нас не изменился рейтинг. Всё круто. Теперь мы можем гарантировать, что наши все значения останутся в рамках разрешённых правил, кроме одного случая. Кроме случая, когда мы при создании нашей структуры укажем

533:32

Speaker C

ей неверные значения. Допустим, рейтингу мы сразу же укажем 100. И в таком случае у нас рейтинг будет 100. Хотя, вообще-то говоря, он должен быть от нуля до 10, а у нас рейтинг 100. То есть мы при создании структуры сразу же записали вот

533:49

Speaker C

этот вот рейтинг неверный. Плюс есть ещё один способ хакнуть эту всю систему. Допустим, у нас изначально был бы рейтинг верный, мы бы всё сделали через методы, но всё равно какой-то недобросовестный программист, недобросовестный коллега взял бы и напрямую бы обратился к нашему рейтингу.

534:05

Speaker C

То есть вот тут вот рейтинг ап мы делаем 1,1, а тут он его ставит 4.545, и это тоже бы сработало. Хотя у нас при создании рейтинг валидный в методе валидации, но вот таким вот прямым доступом к полю недобросовестный

534:20

Speaker C

коллега смог нам всё сломать. Как это пофиксить? Как пофиксить то, что у нас при создании могут быть какие-то баги? И как пофиксить то, что у нас недобросовестный коллега может сразу же обратиться напрямую к полю? Обращение напрямую к полю, как пофиксить, мы

534:36

Speaker C

рассмотрим чуть позже. Пока что мы ещё не знаем достаточно, чтобы воспринять эту информацию, поэтому пока что будем просто с этим смиряться. Совсем скоро мы узнаем, как это пофиксить, но пока что мы с этим смиряемся. А как пофиксить неверные значения при создании? Да,

534:52

Speaker C

очень просто. мы можем написать так называемый конструктор. То есть в гонге мы можем создавать конструкторы для наших структур. То есть конструкторы - это обычные функции, которые называется new, а потом имя структуры, которую мы создаём. В нашем случае это new user.

535:09

Speaker C

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

535:22

Speaker C

Соответственно, нам нужно new usеer создать юзера. Как его создать? Ну, мы, вообще-то, хотим все вот эти вот значения сюда передать, а потом внутри этой функции, внутри конструктора их валидировать и уже создавать нашего пользователя. Ну давайте сделаем. То есть мы будем принимать имя, возраст,

535:39

Speaker C

phone number, isclose и rating. Как мы видим, у нас получилась очень такая длинная строка с объявлением аргументов. И в Голенге можно, вообще-то, это всё сделать читаемым на одном экране. Просто возьмём и перенесём каждый аргумент на новую строчку. Как бы

536:01

Speaker C

суть программы это не изменит, зато просто визуально будет сразу понятно, какие аргументы у нас есть у конструктора. И мы все те же самые проверки будем производить уже внутри вот этого нашего конструктора. Только немножко от обратного пойдём. Давайте, мы пока ещё не знаем, как обрабатывать

536:18

Speaker C

ошибки. А если нам сюда передадут что-то неверное, то это, по сути, ошибка. Пока что мы не знаем, как ошибки обрабатывать. Давайте пока просто условимся, что если какой-то из аргументов был передан невалидный, например, рейтинг 500, то мы будем возвращать пустого юзера. Пустой юзер -

536:36

Speaker C

это вот самый обычный юзер, который не имеет под собой никаких заданных параметров, у которого все значения по умолчанию. Ну и смотрим, если у нас имя пустое, тогда мы сразу же вернём пустого юзера. Если возраст меньше либо равен нулю или возраст больше либо равен 150,

536:55

Speaker C

тогда тоже возвращаем пустого юзера. Если у нас phone number пустой, тогда тоже возвращаем пустого юзера. Если у нас рейтинг меньше нуля или рейтинг больше 10ти, тогда тоже возвращаем пустого юзера. И если мы вот на сорок девятой строчке ещё нигде не

537:17

Speaker C

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

537:28

Speaker C

Соответственно имя name возраст, ну, и так дальше. F number. F number. Is close is close. Rating rating. Всё. Таким образом мы создали конструктор, который принимает какие-то аргументы, принимает значение полей, которые бы мы хотели подставить в нашего юзера. Проводится валидация каждого

537:53

Speaker C

поля. И если валидация прошла успешно, то нам возвращается пользователь, который наполняется нашими данными. Если валидация не прошла хоть где-то, то нам возвращается пустой пользователь. Ну давайте с помощью конструктора уже создадим нашего юзера. Не вот так вот напрямую, как мы это делали, а с помощью

538:08

Speaker C

конструктора. Вот это я всё сотру и напишу user равно new user. И сюда мы уже будем передавать. Нам редактор кода подсказывает, что именно нужно передать. На первом месте имя Данил, на втором месте возраст. Ну, пускай будет 50. Номер телефона там 7

538:28

Speaker C

911 870 70 90. Из close у нас будет fse и рейтин у нас будет, ну, пускай 4, 12. Изначально передаём все валидные значения в наш конструктор, а потом будем выводить юзер на экран.

538:48

Speaker C

USюзер запускаю программу и вижу, что всё, что мы передали в наш конструктор, оно всё прошло валидацию, и переданные нами значения оказались в структуре.

539:00

Speaker C

Если бы мы сюда передали, например, возраст 500, то мы бы увидели, что у нас пустой юзер, потому что не прошёл валидацию по возрасту. Мы бы могли на самом деле добавить сюда ещё и выводы на экран, чтобы более конкретно понимать,

539:15

Speaker C

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

539:37

Speaker C

возраст не прошёл валидацию. Дальше валидирую номер телефона. И если у нас валидация не прошла, мы об этом пишем. Номер телефона не прошёл валидацию. И рейтинг остался. Валидирую рейтинг. И если у нас не прошла валидация рейтинга, тогда мы об этом

540:04

Speaker C

пишем. Рейтинг не прошёл валидацию. Запускаем программу. валидирую имя, валидирую возраст, и возраст не прошёл валидацию.

540:14

Speaker C

Почему? Потому что мы передали некорректный возраст, хотя имя корректное. Давайте проведём всё корректное, передадим. И как мы видим, валидирую имя, возраст, номер телефона, рейтинг. И всё было провалидировано. Нам вернулся пользователь, наполненный нашими данными. А теперь, если бы мы

540:28

Speaker C

передали пустое имя, запускаем. Валидирую имя. Имя не прошло валидацию. Нам вернулся пустой пользователь. С возраста мы уже смотрели, если пустой номер телефона, всё провалидировано, номер телефона не прошёл валидацию, опять пустой юзер нам вернулся. Ну и то же самое, если мы рейтинг передадим 100,

540:46

Speaker C

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

541:05

Speaker C

поставить. Мы это решили благодаря конструктору. То есть мы уже создаём новые экземпляры структуры usеer не напрямую, где можно допустить ошибку, а через конструктор, внутри которого уже прописана вся валидация. И просто мы можем гарантировать нашим коллегам, что если они будут создавать эту структуру

541:22

Speaker C

не вот так вот по-варски, а через конструктор, то мы будем сами валидировать все передаваемые значения и программа будет корректно отрабатывать.

541:32

Speaker C

Можно сказать, что в принципе то недобросовестный коллега, если он действительно недобросовестный, ему может быть всё равно на наши просьбы, и он всё равно может захотеть создать структуру вот таким вот образом. Возьмёт да передаст туда возраст 100.000. тысяч и будет сидеть довольный, ухмыляться,

541:49

Speaker C

типа: "Ха-ха, я обманул систему". В принципе, как и в случае, когда он после создания юзера через конструктор может напрямую обратиться к его возрасту и тоже там поставить что угодно. От этого с вами мы не застрахованы. Нам бы хотелось как-то ограничить доступ нашим

542:05

Speaker C

коллегам к полю Age, чтобы они поле AG могли либо передавать в конструкторе, когда создают нового юзера, либо передавать в методе change ag. чтобы всегда значения, которые попадают к нам в структуру, они проходили валидацию, чтобы не было вот такого вот безобразия.

542:24

Speaker C

То есть у нас в Change AG валидация и в конструкторе у нас тоже валидация на возраст. Тут, на самом деле, сталкиваются два подхода. Первый подход говорит, что давайте мы просто не будем страдать фигнёй, где нужно в программе, где вот этот вот возраст, который у нас

542:39

Speaker C

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

542:53

Speaker C

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

543:05

Speaker C

плохой. Он действительно упрощает жизнь во многих моментах, но если где-то допущена ошибка, она может быть не провалидирована. И тут встречается второй подход. Это когда мы всё взаимодействие с полем H берём на себя, а нашим коллегам мы убираем доступ к

543:23

Speaker C

полю. Дальше мы рассмотрим, как именно этот доступ убирается. В данный момент мы ещё не сможем осознать тех механизмов, которые используются для ограничения доступа. Но пока можете просто мне на слово поверить, что такой подход существует. Мы действительно нашим коллегам можем закрыть доступ к

543:39

Speaker C

этой переменной A, к этому полю H. И весь доступ к этому полю наших коллег будет либо в конструкторе, когда они его задают, либо в методе, где они меняют этот возраст, либо можем им ещё отдельный метод сделать, который будет

543:55

Speaker C

get, то есть просто получить возраст, благодаря которому они смогут получать возраст. Но так как мы тут будем возвращать не указательно наш, а просто копию, то они не смогут, получив это значение, как-то его поменять. Они смогут лишь изменить копию. Нам это не

544:13

Speaker C

страшно. Соответственно, всё взаимодействие сйджем происходит либо change age, сюда четыре, либо через метод user. GetH. Соответственно, у нас всё провалидировано. User 4. То есть вот здесь вот мы change мы поставили возрастчетыре, а потом мы его получили через тоже метод. Соответственно, вся

544:31

Speaker C

работа с этим полем она инкапсулирована в методах, в методах, которые мы берём на себя, где мы уже сами можем смотреть, что мы нигде не совершили ошибок, а наши коллеги будут только пользоваться конструкторами и методами. Но осталось нам только ограничить это самое поле AG.

544:47

Speaker C

Как это делать, мы посмотрим чуть дальше, чтобы коллега недобросовестный не мог просто написать user. H = 500 и всё, у нас опять 500 стал. Дальше рассмотрим, как это спрятать. Повторюсь, кто-то против того, чтобы инкапсулировать всю работу через конструкторы и методы, кто-то любит

545:06

Speaker C

работать напрямую. Кто-то любит и создавать юзеров вот так вот напрямую, и другие структуры, и прописывать сюда возраст. Это два разных подхода, которые встречаются. То есть конструкторы в основном используются всеми, а инкапсуляция работы с полем через методы используется уже далеко не всеми. И тут

545:26

Speaker C

зависит от того, как на вашем рабочем месте принято, где-то принято использовать капсуляцию через методы, чтобы внутри этих методов скрывалась валидация и мы не могли ничего испортить, и у нас не было прямого доступа к переменной к полю H. А где-то

545:41

Speaker C

люди такие челгаи чисто говорят: "Да ну нафиг что-то какие-то методы создавать". Давайте просто здравого смысла будем придерживаться и разрешим всем доступ к этим полям. Просто не пишите туда фигню.

545:53

Speaker C

Два разных подхода, где какой используется, зависит от того коллектива, где вы окажетесь. Таким образом, мы с вами рассмотрели, что такое структуры. Мы рассмотрели, как они вообще описываются. Мы рассмотрели, что такое методы структур. Мы рассмотрели, что у методов структур могут быть

546:11

Speaker C

ресиверы по значению, могут быть ресиверы по указателю. Мы узнали, когда какой ресивер лучше использовать. Мы узнали, что у структур принято прописывать конструкторы. Мы узнали, что у структур могут быть поля, которые могут быть либо закрыты, либо открыты.

546:29

Speaker C

Тем самым мы, в принципе, познакомились с сутью самой структур. Структуры в голнге используются просто повсеместно.

546:36

Speaker C

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

546:55

Speaker C

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

547:07

Speaker C

[музыка] Следующая довольно важная и большая тема на нашем рассмотрении - это модули и пакеты. Посмотрим, что такое модули, что такое пакеты. Наконец-таки узнаем, что вот это вот в начале мы всегда пишем package main. Узнаем, для чего вообще эти модули и пакеты существуют. Ну,

547:24

Speaker C

короче, по классике. Поехали. Сперва давайте взглянем на следующие иллюстрации. Это, считайте, структура папок. Вот наша папка стадия. В ней есть какой-то main файл, greeting go file.

547:40

Speaker C

Также в этой папке стадии есть другие папки users, database и tools. То есть папка users, она лежит в папке stud. И в этой папке users три файла: users 1, users 2, users 3. Ну, все с расширением тоgo, все гошные файлы. Папка database,

547:56

Speaker C

тут файлы, которые относятся к этой самой папке, какие-то файлы с базой данных и какие-то. Есть у нас утилиты tools, тут есть логер, метрики. Сейчас вообще абсолютно не обязательно знать, что такое база данных, что такое логер, что такое метрики. Просто поймите, что

548:14

Speaker C

это какая-то схема, которая представляет структуру папок. У нас есть наш проект study, и он содержит следующую структуру папок. Есть у него main Goфайл, в этой же папке Greeting Goфайл. Ну и в папке Stud помимо этих двух файлов ещё другие

548:30

Speaker C

папки. и в каких-то из этих других папок ещё какие-то папки. Ну и так далее. Это наш проект в Голенге. Вот такой вот проект отдельный называется модуль. То есть это всё можно сказать одним словом модуль. То есть модуль - это, в

548:47

Speaker C

частности, какой-то проект, в котором есть главный файл и какие-то там другие папки, файлы или, может быть, только главный файл, но просто какая-то отдельная программа, которую мы можем запустить, она будет что-то делать. Это модуль. Также в Голенге помимо написания

549:05

Speaker C

программ есть ещё немаловажная часть - это написание библиотек. Что такое библиотеки? Библиотеки - это просто наборы каких-то заготовленных уже файлов, которые мы можем использовать в наших программах. То есть вот это библиотека, и мы какие-то из этих файлов можем использовать в нашей программе. Ну

549:24

Speaker C

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

549:43

Speaker C

инструментами FMT. Вот. То есть бывают какие-то отдельные программы, которые мы пишем сами и можем запускать. Бывают какие-то отдельные библиотеки, которые мы можем либо писать сами, либо они уже кем-то за нас написаны, и мы просто используем оттуда какие-то отдельные

549:58

Speaker C

части. Ну вот, в данном случае мы из стандартной библиотеки взяли ящик с инструментами FMT. Из этого ящика с инструментами FMT мы использовали printl. То есть мы просто взяли и подключили часть стандартной библиотеки для того, чтобы через пакет FMT что-то

550:12

Speaker C

выводить на экран. Вот эти библиотеки отдельные - это тоже модули. Вот два типа модулей в Голнге. Программы, которые мы пишем, которые можем запускать, и какие-то отдельные библиотеки, в которых есть много разных там файлов, много разных поддиректорий.

550:28

Speaker C

И мы всё это можем использовать. То есть, если посмотреть на вот эту иллюстрацию, которую я сделал для библиотеки, можем посмотреть, что это какая-то библиотека, в которой есть сетевое взаимодействие и в которой есть какой-то код для работы с операционной

550:41

Speaker C

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

550:58

Speaker C

разберём это на практике. Пока для начала необходимо ознакомиться с теорией. Раз. Модуль, два, модуль. Что же такое пакеты? Пакеты - это вот эти вот самые папочки. То есть просто какая-то отдельная папка - это считай отдельный пакет. Вот у нас получается

551:14

Speaker C

отдельный пакет loger, отдельный пакет matrix, отдельный пакет Database, отдельный пакет users. И в модуле с библиотекой тоже самое. Вот отдельный пакет Network, вот отдельный пакет Fil. Вот отдельный пакет Power. То есть, что такое пакет? Пакет - это просто какая-то папка, в которой лежат

551:35

Speaker C

файлы на одном уровне. То есть вот, например, Tools. Если бы тут лежали какие-то файлы, да, допустим, у нас в Tools лежал бы файл to.go. Вот в папке Tools у нас лежит файл to.goo. Тогда Tools - это тоже какой-то пакет. И

551:49

Speaker C

внутри пакета Tools есть другие пакеты. Loger matrix. Это уже отдельные пакеты. Несмотря на то, что они лежат в папке Tools, это отдельные пакеты. То есть пакет, повторюсь, это просто какая-то папка с гошными файлами на одном уровне.

552:06

Speaker C

То есть, если у нас пакет Tools и в этом пакете Tools какие-то другие папки с кодом, то этот код, который в этих других папках лежит, он уже не относится к пакету Tools, он уже относится к тому пакету, в папке которого они лежат. То

552:21

Speaker C

есть пакет - это просто папка с гошными файлами на одном уровне. То есть если какие-то гошные файлы лежат вот на одном уровне вложенности в нашей структуре директорий в одной папочке, это всё можно назвать одним отдельным пакетом.

552:36

Speaker C

То есть есть модули, это такой самый большой уровень абстракции. Либо библиотека это может быть, либо какая-то целая программа. А в этой программке, если поближе присмотреться, есть отдельные пакеты. Ну и в библиотеке тоже могут быть какие-то отдельные пакеты. То

552:50

Speaker C

есть, повторюсь, модуль - это либо наша целая огромная программа, либо какая-то библиотека сторонняя, ну или которую мы сами написали, тоже какая-то отдельно библиотека. Это модули, а пакеты - это просто папочки с файлами. Просто как вот мы в пакет можем положить несколько

553:04

Speaker C

файлов гошных, вот это и будет называться пакет с точки зрения языка программирования. И ещё раз повторюсь, если у нас в каком-то пакете, например, tools лежат другие папки, это уже другие пакеты. И код, который в них находится, к пакету Tools не относится. код,

553:19

Speaker C

который находится в этих папочках, будет относиться к пакету именно этих папочек. То есть вот у нас тут, если файлы loger 1, loger 2, это всё относится к пакету loger, не к tools, но к пакету loger.

553:31

Speaker C

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

553:52

Speaker C

описываете в каком-то из файлов, это будет видно всегда в соседнем файле. Но если вы описываете что-то, допустим, в пакете Users и потом хотите к этому чему-то получить доступ из пакета Database, уже будет не всё так просто.

554:09

Speaker C

уже мы в пакете users сможем разделять, что именно файлы из других пакетов смогут у нас увидеть, а чего они увидеть не смогут. То есть мы на уровне пакета users сможем сокрыть какие-то функции, какие-то структуры, какие-то поля структур, какие-то методы этих структур

554:30

Speaker C

настолько, что в рамках других пакетов этого не будет видно. Поэтому, повторюсь, на уровне одного пакета всё, что написано в файлах одних, видно в других файлах. Это же относится и к главному пакету. То есть вот это наш главный пакет main. И ещё какие-то

554:48

Speaker C

файлы, которые могут быть на уровне самой нашей главной папки. Это всё главный пакет. И все остальные файлы, которых может и не быть, но они могут и быть. И лежать они должны в той же папке, что и main.go. Тогда они будут

555:01

Speaker C

относиться к этому главному пакету. И всё, что мы напишем в файлах, которые лежат на том же уровне, что и main. Всё это будет доступно изнутри нашего файла main.g. И наоборот, всё, что мы напишем в main.go, будет доступно в других

555:16

Speaker C

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

555:31

Speaker C

многое непонятно, но познакомились с таким понятием, как модуль, и с таким понятием, как пакет. Раз. Пакет, два, пакет, три, пакет. То есть модуль - это, по сути, самый большой пакет с пакетами, если можно так выразиться. Модуль - самая большая абстракция наших программ

555:50

Speaker C

или наших библиотек. А если более детально присматриваться, то в них уже будут разные пакеты. в которых лежат какие-то файлы. В этих пакетах могут лежать папки с другими пакетами, но, в общем-то говоря, модуль - это либо наша целая программа, либо наша целая

556:05

Speaker C

библиотека, а пакет - это просто какая-то отдельная папочка с файлами. И все файлы, которые лежат в этой папочке, они относятся к этому пакету. Но если у нас в пакете другие папочки, то это уже другие пакеты, и для них будут работать

556:20

Speaker C

все те же самые правила, которые мы уже обсудили. Ну, теперь предлагаю перейти от теории, наконец-таки, к практике.

556:26

Speaker C

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

556:42

Speaker C

в папке Stad, это не просто какой-то отдельный main. Файл, это целый модуль, который может иметь разные пакеты под собой. Для того, чтобы создать модуль, мы просто в консоли пишем go, modit. И после этого название модуля абсолютно любое. Ну, я назову модуль study, потому

557:01

Speaker C

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

557:11

Speaker C

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

557:26

Speaker C

дошли, поэтому просто можем прописать её на всякий случай и всё. Пока не нужно задумываться о том, что эта команда вообще делает. Мы объявили модуль. Что это значит? Мы сказали языку программирования, что теперь то, что находится в папке stud, а именно тут наш

557:40

Speaker C

go. Файл, всё, что находится в папке stud - это модуль какой-то, именно модуль stud. То есть мы сказали, что вот это теперь большой какой-то модуль, и мы в нём можем создавать разные пакеты, разные файлы и их использовать. Ну

557:57

Speaker C

давайте не будем ходить вокруг до около и сразу же создадим пакет. Назову этот пакет. То есть помним, что пакет - это по сути просто какая-то отдельная папка.

558:08

Speaker C

Пакетн. Ну и создам в нём файл тоже. Файл можно назвать как угодно. И объявлю тут пакет.

558:16

Speaker C

До этого мы всегда объявляли package main. Почему? Да потому что в программе должен быть один главный пакет, в котором находится главная функция, из которой начинается выполнение нашей программы. Но другие пакеты должны называться по-другому. Ну вот у нас гритинг, да, поэтому я его и назову

558:34

Speaker C

гритинг. То есть этот бакет, он будет просто служить тем, что в нём будет написана функция say hello, которая будет выводить на экран Hello Goleng Packages. Сохраняем. И теперь, как мы видим, у нас есть главный файл, а есть отдельная папка. То есть это отдельный

558:56

Speaker C

пакет, в котором у нас функция say hello. Как нам эту функцию использовать? Если мы просто её напишем, say hello, то как мы видим, что что-то, ну, ничего нету. Мы вот наводим undefine, то есть неопределя, непонятно, что это такое.

559:11

Speaker C

Для того, чтобы вызвать функцию из какого-то пакета, нужно посмотреть название этого пакета. У нас пакет называется. Написать название этого пакета. И, как мы видим, язык программирования нам сразу подсказывает, что у нас есть какой-то пакет. Он находится в модуле стадия. Просто можем

559:28

Speaker C

нажать Enter, и автоматически редактор кода нам подключит наш пакет. И мы можем после названия этого пакета написать точку и увидеть функции, которые мы в нём прописали. Тем самым вызвать say hello. Давайте запустим нашу программу. И как мы видим, сначала у нас

559:49

Speaker C

функции main, отсюда именно начинается выполнение нашей программы из главного пакета, из главной функции. выявилась Hello World, а потом мы вызвали функцию из пакета Greeting. Повторюсь, на винде и на Линуксе можно нажать Ctrl левую кнопку мыши, на Mocs Command, левую

560:05

Speaker C

кнопку мыши. И мы тем самым перейдём сразу же к функции или к сущности, к структуре, там, к методу, который описан в другом пакете, в другом месте. Вот здесь у нас просто пакет и функция say hello, которая выводит на экран Hello

560:19

Speaker C

Goong packages. Этим самым мы с вами создали отдельный пакет, объявили его и создали в нём другую функцию. Теперь в этом пакете мы можем создавать сколько угодно файлов. Можем создать файл какой-нибудь bet.go. Что значит bed? То есть тут мы

560:36

Speaker C

уже будем выводить на экран не приветствие, а какие-нибудь плохие вещи. Ну, для того, чтобы создать ещё один файл в том же пакете, нам нужно объявить вначале, что это тот же самый пакет.

560:50

Speaker C

Почему мы не можем тут написать какой-нибудь другой пакет? Потому что тогда goeng не понимает, что в папке Greeting, а он будет воспринимать папку как пакет, объявлено два разных пакета, и он не сможет выбрать, какое же из этих названий в итоге должно быть настоящим.

561:07

Speaker C

Поэтому нужно всегда однозначно указывать название пакетов. Если мы в каком-то файле объявили, что у нас это пакет гритинг, то везде в рамках этого пакета нам нужно говорить, что это пакет. Ну и тогда у нас goeng сразу поймёт, что это отдельный пакет,

561:23

Speaker C

отдельная папочка, в которой у нас содержатся различные функции. Ну и тут мы можем написать функ say bed.

561:32

Speaker C

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

561:54

Speaker C

теперь save Bed. Сохраняю, запускаю. Ну и как мы видим, наш ТПХ выводится. Плюсом ко всему всё, что написано в одном файле пакета, оно доступно в других файлах пакета. Также будто это написано в том же файле. Что я имею в

562:11

Speaker C

виду? Ну, к примеру, у нас тут, допустим, будет ещё один файл. Назову его int, ну, просто int. Опять же, объявляю пакет. Что в этом файле будет?

562:21

Speaker C

В этом файле будет одна функция give me int, которая будет возвращать integer, да, просто, например, число 55. Всё.

562:30

Speaker C

Обычная функция, которая возвращает число 55. Если мы хотим использовать эту функцию в мейне, то нам опять нужно лезть в пакет. Ну вот I равно нам нужно лезть в пакет и доставать оттуда эту функцию give me int. Ну и потом мы можем

562:45

Speaker C

вывести это I на экран. Вот I55. Но если мы захотим использовать вот эту функцию give me int в рамках того же пакета, в котором она создана, то мы можем это делать напрямую. То есть вот, допустим, функция say hello. Тут я

563:04

Speaker C

возьму и скажу, что J равно give me int. Мне уже не нужно будет писать название пакета, потому что понимает, что если я просто написал название какой-то функции или какой-то структуры, какого-то конструктора, то это значит, что искать нужно в том же пакете. То есть, если я

563:23

Speaker C

до этого не писал никаких приставок, значит, искать нужно в том же пакете. Ну, а так как give me in у нас находится в том же пакете, в пакете, то мы можем без проблем его вызывать. Ну и давайте я на экран

563:34

Speaker C

выведу. From say hello. И тут j. Запускаю. Ну и как мы видим, что у нас сразу же после вывода Hello Go packages вывелось from say hello 55. То есть мы вызвали вот эту функцию give me intхвок, просто как будто бы она у нас

563:51

Speaker C

написана в этом же файле, но она написана в другом файле, просто в том же пакете, поэтому мы без проблем можем её вызывать. В мейне же нам нужно указать, что это за пакет. Потому что, если мы просто напишем give me int в главном

564:05

Speaker C

пакете или в каком-нибудь другом, то будет язык программирования эту функцию искать в пакете main, а в пакете main её нету. Поэтому нужно конкретно указывать, в каком пакете эта функция находится. С пакетами и с доступами к различным сущностям в этих пакетах есть одна очень

564:24

Speaker C

забавная особенность. Давайте посмотрим. Вот, к примеру, я опять же вызываю нашу функцию из пакета Greeting Give Me intду это на экран. Вот. I, вот она наша I. Запускаю.

564:41

Speaker C

Ну вот I55. То есть мы обратились к пакету Greeting. В этом пакете мы обратились к функции give me int. В этой функции у нас вернулось 55 целочисленная. И мы её положили в переменную i и вывели на экран. О'кей. А

564:56

Speaker C

теперь что будет, если я функцию give me in назову с маленькой буквы? Ну, казалось бы, какая разница, с большой буквой или с маленькой. А теперь начинает подчёркивать как ошибка, что он не может найти give meми. Почему? Ну-ка давайте вот ещё раз. Greeting точка say

565:13

Speaker C

bad есть, say hello есть, а give me in нету. Где же give me in? Куда он делся?

565:19

Speaker C

Давайте-ка я верну большую букву. Сохраняю файл. Оп, появился give me in. То есть, когда мы в пакете пишем что-то с маленькой буквы, функцию, структуру, метод структуры, если называется с маленькой буквы, то эта функция, структура или метод, они перестают быть

565:38

Speaker C

доступными в других пакетах. То есть теперь give me in я могу использовать только на уровне того же пакета, в котором она объявлена. Вот объявлена функция give me in на уровне пакета Greeting. Ну, в том же пакете я могу её

565:52

Speaker C

использовать, да, без проблем. Но в других пакетах я уже не могу эту функцию использовать. Её уже для меня как бы не существует. Почему? Потому что я, назвав функцию give me in с маленькой буквы, я сокрыл её от других пакетов. И это та

566:11

Speaker C

самая вещь, про которую я говорил. Что нам делать, если у нас, к примеру, мы разрабатываем какой-то отдельный пакет usеer. Вот наш пакет usеer. Тут у нас наша структура, у которой есть имя и возраст.

566:28

Speaker C

И мы не хотим, чтобы у кого-то был доступ к этому возрасту, чтобы он мог просто сделать. Вот, например, я создам нового юзера. Он в пакете USюer. Кстати, смотрите, есть два разных пакета usеer.

566:40

Speaker C

Один в модуле OS каком-то, а другой в нашем модуле стадии. Нужно выбрать конкретно наш из модуля стадии. Нажимаем Enter. Точка. И вот она наша структура user. Собственно, мы из пакета user взяли структуру usеer, положили в переменную u. И вот мы хотим, чтобы

566:57

Speaker C

кто-то нехороший не мог вот взять наш пакет, который мы разрабатываем, взять там юзера и положить туда возраст 500.

567:05

Speaker C

Как вот сделать, чтобы у человека, чтобы у нашего недобросовестного, того самого коллеги, не было доступа вот к этому полю? Да, мы просто можем взять и это поле назвать с маленькой буквы. И теперь у человека не будет доступа к этому

567:18

Speaker C

полю. Он вот будет ставить точку. У него только name есть. Почему? Ну, потому что name с большой буквы. Если не хотим, чтобы был доступ к полю name, name тоже с маленькой буквой пишем и всё. И нету доступа к этим полям. Он их никак не

567:30

Speaker C

сможет испортить. Если мы организуем всю работу с этой нашей структурой usеer только через конструктор и методы, ну вот, например, у нас конструктор есть, он принимает имя string и возраст intрять, что если у нас имя пустое, тогда он возвращает пустого юзера. Если

567:54

Speaker C

H меньше либо равен нулю или больше либо равен 150, тогда тоже возвращает пустого юзера. А если всё о'кей, тогда возвращает юзера, у которого имя то, что мы передали, и возраст тот, что мы передали. То есть мы теперь можем

568:12

Speaker C

задавать имя и возраст сразу же при создании только через конструктор. Вот здесь вот мы в скобочках уже ничего с вами задать не сможем. То есть мы вот будем писать name, а его, ну, нету, как бы мы не можем. Мы можем только пустого

568:24

Speaker C

юзера создать таким образом. Но пустую структуру никто использовать не захочет. У неё все значения по умолчанию, с ней ничего не сделать. Поэтому хочешь не хочешь, придётся создавать юзера через конструктор. А потом, если человек захочет поставить юзеру новое имя

568:38

Speaker C

какое-нибудь там, да, set new name, тогда мы уже сможем в конструкторе валидировать, что новое имя, оно у нас пустое или нет. То есть, если не пустое, тогда мы ставим новое имя, иначе ничего не делаем. То же самое с

568:58

Speaker C

[аплодисменты] возрастом. То есть, если у нас возраст больше нуля и меньше 150, тогда мы можем наш возраст поставить.

569:17

Speaker C

Таким образом мы организовали нашу структуруер. Мы вот разрабатываем этот пакет USр, да, нам дали задачу разработать структуру. И мы таким образом можем нашим коллегам запретить просто каким бы то ни было способом нашу структуру сломать, потому что они теперь

569:34

Speaker C

всю работу с полями, которые важно сохранять в валидном состоянии, то есть нам важно, чтобы имя было не пустое, чтобы возраст был в этом промежутке, мы им даём работать только через конструктор и методы. Ну, если они хотят получить имя, то можем им сделать так

569:52

Speaker C

называемые геттеры. гter - это get и что-то там name, например, да, будем возвращать ему имя. То же [аплодисменты] самое get a будет возвращать наш возраст. Всё, тут у нас никаких указателей, возвращаются обычные копии.

570:15

Speaker C

И тем самым, если кто-то захочет узнать, какой возраст лежит в структуре юзера, он получит копию, но не указатель, а просто копию. Поэтому он не сможет как-то это поле изменить. Он сможет его изменить только через метод set new name. А в этом методе у нас прописана

570:33

Speaker C

валидация. Таким образом, мы инкапсулировали не только логику по валидации новых значений, но и инкапсулировали поля структуры, к которым не должно быть доступа у наших коллег для того, чтобы они просто не могли тут ничего сломать. Вот мы говорим, что вот есть пакет usеer, ты

570:51

Speaker C

можешь его использовать, делать с ним, что хочешь. В любом случае значения, которые лежат в пользователе, будут валидные, программа не сломается. Я об этом позаботился. Просто пользуюся конструктором. Вот newюer, там, например, имя какое-нибудь там Данил и возраст 50. И потом, если ты захочешь

571:11

Speaker C

что-то с этим юзером сделать, ты можешь только ему поставить возраст или имя, или получить их. Но если ты захочешь поставить какой-нибудь некорректный возраст, я просто ничего не сделаю. И тем самым ты не сможешь сломать. А если ты захочешь сломать мне возраст, то ты

571:24

Speaker C

не сможешь этого сделать. У тебя вот доступа к нему не будет. То есть на уровне пакета мы можем сокрывать какие-то поля, какие-то функции, как у нас было вот give me in. Для того, чтобы доступ к этим полям и функциям

571:39

Speaker C

сохранялся только в разрабатываемом пакете, но не было к ним доступа в других пакетах. Для чего? Ну, опять же, просто для безопасности разработки, что мы разработали какой-то пакет, но наши коллеги, которые этим пакетом будут пользоваться, просто не смогут как-то

571:56

Speaker C

что-то сломать. Мы им просто не позволим тем самым, что у нас есть валидация и весь доступ к чувствительным полям. А вот возраст, да, и имя - это довольно чувствительно у нас поле, потому что если мы возраст поставим 500, у нас

572:09

Speaker C

программа может вообще отображать какую-то фигню, она может сломаться в теории. То есть это чувствительное поле.

572:14

Speaker C

или если имя у нас пустое. Представьте, вы в социальной сети заходите на чью-то страницу, а там пустое имя, ничего не написано. Ну и как-то странно. То есть вот во ВКонтакте, например, к вам добавляется кто-нибудь в друзья, вы заходите, там имя пустое, возраст 500

572:27

Speaker C

лет. Ну и вы такие: "Блин, что-то как-то странно". Поэтому это чувствительные поля, и мы их валидируем. Доступ предоставляем только через сеттеры и гттеры. А сами поля у нас сокрыты благодаря тому, что первая буква у них маленькая. Как только первая буква

572:42

Speaker C

становится большой, если навести на какое-нибудь название, нажать F2, то можно будет сразу во всех местах его переименовать. Вот, допустим, у нас name с большой буквы. Так у меня сразу и доступ к нему получится. Вот он namйм, я смогу сюда поставить пустую строчку,

572:56

Speaker C

ехитно потереть ручки, убежать, и всё, у меня будет юзер, ну, с пустым именем. Чтобы такого не было, мы можем назвать name это поле с маленькой буквы, и никто не получит к нему доступ, кроме разработчика вот этого пакета. Но

573:11

Speaker C

повторюсь ещё раз, что в Голенге среди разработчиков есть два подхода. Первый - это который я показал, где мы сокрываем вот эти вот чувствительные поля и предоставляем к ним доступ только либо через конструктор, либо через сетеры, гетеры, но прямого доступа нету, чтобы

573:27

Speaker C

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

573:46

Speaker C

совершать ошибок, не писать тоже пустое имя или возраст 500. Не скажу, что какой-то из этих подходов лучше.

573:52

Speaker C

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

574:10

Speaker C

Васёк нам не пришёл и ничего не сломал. Но в каких-то командах принято использовать первый подход, в каких-то командах принято использовать второй подход. Это всё зависит от того, в какую команду вы, собственно, попадёте. Ну и тот, и тот подход имеет право на жизнь,

574:26

Speaker C

поэтому что лучше, я тут судить не берусь. Что имеем? Мы можем, объявив модуль, сказав нашему языку программирования, что сейчас тут, короче, будут разные пакеты, разные файлы. Для этого мы объявляем модуль. И вот объявив этот самый модуль, мы можем

574:42

Speaker C

создавать разные папки в нашем проекте, можем там писать разные файлы, мы можем разные функции в этих самых файлах прописывать. И что самое главное, назовимы функцию или поле, или структуру с большой буквы, они сразу же станут доступны ото всех других пакетов. Если

575:01

Speaker C

мы назовём что-то, функцию, структуру, поле структуры, метод с маленькой буквы, всё это функция, структура, метод, поле будет доступно только в рамках этого же пакета. В других пакетах уже доступно не будет. То есть, если мы создадим какую-то структуру, например,

575:20

Speaker C

human назовём её с маленькой буквы, ну вот она просто пустая структура у нас пускай будет. И захотим из пакета user, а ведь эта структура hюan, она у нас в пакете usеer, достать её. Ну пишем пакет usеer точка. И тут никакого хюмана нету,

575:36

Speaker C

он в другом пакете уже не доступен. Этот hхюман он доступен только в рамках того же пакета, в котором он описан. Почему? Потому что он с маленькой буквы называется. Если мы его назовём с большой буквы, то он сразу же станет доступен из

575:54

Speaker C

другого пакета. То есть это работает и на функции, как give me in, и на структуры, как вот human, даже на методы структур. То есть давайте вот этот get a смотрим, он у нас с большой буквы.

576:06

Speaker C

метод get структуры usеer. Вот он. Get H у нас самый первый. Теперь давайте его с маленькой буквы назовём. Ну, как мы видим, сразу подчёркивает красным. Если мы точку поставим, мы никакого тйджа не увидим.

576:18

Speaker C

Почему? Потому что мы, назвав его с маленькой буквы, сокрыли от других пакетов. И теперь этот get user. То есть, если я в каком-то другом методе захочу вызвать get AG, вот он у меня будет с маленькой буквой. Но в

576:36

Speaker C

других пакетах доступен не будет. Для чего? Ну, я уже сказал, мы можем от других пакетов, от других наших коллег, от других людей, которые будут использовать наш пакет, сокрыть какие-то чувствительные или ненужные данные для того, чтобы они им не мешали, для того,

576:52

Speaker C

чтобы наши коллеги ничего нам не могли сломать. Ну, к примеру, у нас тут будут какие-то вспомогательные функции, там helpпер 1, helper 2. И вот эти вот функции мы хотим, чтобы были видны только на уровне пакета users, но чтобы, когда мы

577:09

Speaker C

использовали этот пакет из других мест, то мы никаких хелперов не видели, потому что они будут просто захломлять нам наши подсказки в редакторе кода. Вот смотрим usеer. Тут вот Helper 1, Helper 2, они нам могут быть вообще тут не нужны. Это

577:27

Speaker C

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

577:41

Speaker C

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

578:02

Speaker C

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

578:20

Speaker C

видим, у нас тут в нашем пакете USюзер, несмотря на то, что есть какие-то другие функции, у нас есть возможность просто создать нового пользователя, передать туда какое-то имя, там возраст, там вот usеer 2. И потом через этого юзера у нас уже есть возможность

578:36

Speaker C

там получить его возраст, имя и поставить. Всё, ничего лишнего. Никаких вот этих вот helpпер 1, 2, которые нам в принципе не нужны будут в других пакетах, у нас нету. Ну вот такие пироги. То есть мы всегда с вами писали в начале package

578:51

Speaker C

main, потому что у нас был главный пакет. Главный пакет - это пакет, в котором функция main. То есть какн вообще смотрит на программу, когда мы её запускаем. Мы пишем go run. Ну и что-то там вот название файла main Go. В этом

579:06

Speaker C

файле обязательно, чтобы был главный пакет. Обязательно. То есть давайте вот тут вот сделаем вывод на экран. Hello world. Вот. Запускаем gounmain. Всё запускается. Если тут бы пакет назывался lowl, нам бы сказали, что типа package не главный, потому что запускать мы

579:25

Speaker C

можем только главный пакет. Наш пакет должен быть главный. И вот в главном пакете у нас главная функция, отсюда начинается выполнение. Поэтому мы всегда и прописывали package main. Мы говорили языку программирования, что вот этот вот файл main GO, он в главном пакете,

579:40

Speaker C

значит, где-то тут должна быть функция main Go. И это обязательно, потому что наш пакет является главным, в котором главная функция. И отсюда именно нужно начинать выполнение нашей программы, потому что у нас могут быть другие какие-то пакеты. Языку программирования

579:55

Speaker C

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

580:10

Speaker C

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

580:27

Speaker C

Greгритинг? Непонятно. Нужно, чтобы везде называлось одинаково. Таким образом, мы рассмотрели техническую часть пакета, но теперь остался вопрос: а зачем оно нам всё надо? Почему мы не можем по старинке, как раньше, всё писать в мейне? Ну вот, ну почему? Ну

580:43

Speaker C

давайте посмотрим. Допустим, у нас есть вот структура юзера со своими методами какими-то. Вот она у нас как раньше прописана в главном файле. Вроде всё круто. У нас юзер, мы можем вызывать конструктор метод. Посмотрите, вот это 40 строк кода, там 35-40 строк. Это мы

580:59

Speaker C

написали там за пару минут разработки. А теперь представьте, что у нас наша социальная сеть разрабатывается не одну минуту, она разрабатывается несколько лет. Соответственно, вот эта структура юзера и то, что она может делать, оно будет ограничиваться не четырьмя методами и 35 тире40 строчками кода. Оно

581:19

Speaker C

может расползтись уже на тысячи, десятки тысяч строк кода. А вы представьте, что такое десятки тысяч строк кода в одном файле. Это просто, извините меня, капец, но в этом будет невозможно разобраться. Какие-то разные методы там будут, разные структуры. У нас же в коде

581:36

Speaker C

не только структура usер будет, ещё и другие структуры. У нас там могут быть другие сущности в нашей социальной сети, которые мы в теории разрабатываем. И вот посмотрите, как это выглядит. Вообще ничего непонятно, просто какая-то куча кода. Поэтому мы, конечно же, захотим

581:52

Speaker C

этого юзера потом со временем куда-нибудь вынести. Ну куда мы его можем вынести? Ну, мы можем этого юзера с вами взять, да, и вынести в отдельный файл, создать тут user. И вынести сюда юзера и удалить его из мейна. Можем мы так сделать? Можем.

582:09

Speaker C

Да. Всё, у нас типа тот же самый главный пакет, потому что он находится в одной папке с нашим главным файлом. То есть это всё тот же самый пакет. Повторюсь, пакет просто какая-то отдельная папка с кодом. Всё, весь код в этой папке

582:22

Speaker C

относится к пакету какому-то одному. Всё. Если мы тут создадим ещё одну папку, это уже будет другой пакет. И в нём будут файлы, относящиеся тоже к другому пакету. То есть всё, что в папке гритинг, за исключением других папок -

582:37

Speaker C

это пакет гритинг. То же самое с мейном. Всё, что в нашей папке, где находится main- это всё тоже пакет main. Ну вот взяли, да, вынесли юзера типа в другой файл. Ну всё, круто. Теперь представьте, что этот файл опять начнёт разрастаться,

582:50

Speaker C

но мы захотим создать ещё какой-нибудь файл. Вот у нас usюер один. Теперь user 2 будет, потом там usер 3. А теперь представим, что у нас не только usер, а ещё и какой-нибуд взаимодействие с базой данных. Потом точно так же этот файл

583:06

Speaker C

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

583:25

Speaker C

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

583:35

Speaker C

Разрабатывать это будет практически невозможно, разобраться в этом будет практически невозможно. У нас куча одинаковых каких-то огроменных файлов, там по несколько тысяч строк кода, всё в одной папке. Очень грустненько. Как это решается? Да, с помощью тех пакетов, которые мы с вами прошли, мы берём и

583:51

Speaker C

вместо того, чтобы создавать миллион файлов в главном пакете, которые относится к юзеру, мы возьмём и для юзера создадим отдельный пакет. И если наш юзер будет разрастаться, мы уже в этом пакете будем создавать ему новые файлы и называть их как-нибудь. Это

584:06

Speaker C

будет относиться всё к пакету usеer. И мы будем знать, что если нам нужен usеer, мы просто идём в папочку usеer. И эта папка usеer, как бы сильно она не разрасталась, она никак не будет влиять на другие пакеты. И другие пакеты не

584:18

Speaker C

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

584:36

Speaker C

всё довольно понятно, удобно. Когда у нас всё в одной папке, это превращается просто в какой-то наколхоженный код коричневого цвета, когда это всё в разных папочках, в разных пакетах, это всё круто. Хорошо, с пакетами разобрались. Теперь давайте поговорим, зачем нам нужна такая концепция, как

584:53

Speaker C

модули. Напомню, модули - это как программы, которые мы разрабатываем, так и какие-то сторонние библиотеки, из которых мы просто можем вытаскивать какие-то отдельные пакеты для использования. Благодаря тому, что мы объявляем нашу программу как модуль, мы можем благодаря этому использовать

585:10

Speaker C

другие модули. То есть кто-то написал какую-то библиотеку и сказал, что она модуль. Мы написали свою программку и сказали, что она модуль. И благодаря этому мы можем брать эту стороннюю библиотеку и использовать её. Давайте посмотрим, как это может выглядеть. Ну,

585:25

Speaker C

к примеру, есть вот такая вот замечательная библиотека. Называется она ПП от автора Какабун. Она позволит нам красиво выводить на экран наши структуры. То есть, что я имею в виду?

585:38

Speaker C

Ну вот, к примеру, у нас есть наш юзер. Обращаемся к пакету юзер. Создаём нового юзера. Имя пускай будет Петя. И ему 30 лет. Ну и давайте выведем нашего юзера на экран с помощью ящика с инструментами FMT. Ну, как уже, наверное, вы могли

585:53

Speaker C

понять, FMT - это тоже какой-то просто отдельный пакет, но он встроен в язык программирования, поэтому перед ним не стоит никакого модуля, а просто FMT.

586:01

Speaker C

сразу пакет можно вызывать и выведем нашего юзера. Запускаем программу. Ну и видим, что что-то Петя 30, что-то непонятно какое поле чем является. Просто Петя 30, какие-то скобочки. Ну как-то не очень. А вот есть библиотека. Вот повторюсь, вот это ПП.

586:21

Speaker C

Она призвана выводить наши структуры красиво, ещё и с разными цветами. Для того, чтобы нам использовать какую-то библиотеку, которая размещена там на Гитхабе или где-нибудь ещё, нам нужно скопировать её, вот этот вот адрес, ну, без https. Копируем. После этого в

586:38

Speaker C

директории, где у нас файл, а у нас файл в директории stud, вот он гомо, мы пишем go get и потом даём ссылку на вот эту библиотеку. Нажимаем Enter и видим, что-то там скачалось, что-то добавилось.

586:51

Speaker C

Что произошло? Мы сказали нашему языку программирования, что возьми, пожалуйста, вот эту вот библиотеку по вот этой вот ссылке и добавь её к нам, то есть скачай, то есть установи как бы вот эту вот библиотеку, чтобы мы могли её использовать. Что на самом деле

587:05

Speaker C

произошло? Язык программирования по адресу, который мы ему передали, скачал файлы этой библиотеки, где-то там у себя закшировал и в файл go. Он добавил эту библиотеку как зависимость. То есть, что такое зависимость? Теперь мы в нашей программе, если эту библиотеку будем

587:23

Speaker C

использовать, то мы будем от этой библиотеки зависеть. И зависеть не просто от этой библиотеки, а от конкретной её версии. То есть у этой библиотеки может быть много разных версий. Вот мы конкретно взяли самую последнюю актуальную версию автоматически 301. Соответственно, если

587:41

Speaker C

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

587:57

Speaker C

И в консоль пишем go modidy. Что такое modди? Вообще, годи - это очень умная команда. Она, во-первых, смотрит, что мы действительно используем ПП библиотеку в нашем коде. Если мы эту библиотеку использовать в нашем коде не будем, она автоматически после гомотай удалится из

588:15

Speaker C

наших зависимостей. Ну, давайте тут пока оставлю третью версию. Удалю использование библиотеки ПП. Всё, мы её нигде в программе не используем. Я пишу Got Tidy. Оп, исчезла эта библиотека со всеми её необходимыми библиотеками, потому что мы их просто не используем. И

588:32

Speaker C

всё, у нас из нашего модуля они исчезли, потому что они нам не нужны. Нам больше не нужно следить за зависимостями ненужными. Нам больше не нужно следить за ними как за зависимостями. Нам больше не нужно их скачивать при запуске

588:44

Speaker C

программы, потому что мы их не используем. А теперь, если мы эту библиотеку опять начнём использовать printl user и после этого опять напишем go ti, то библиотека сразу вернётся в наш go. Файл. Когда мы впервые только скачиваем библиотеку, нам нужно её

589:02

Speaker C

скачивать через goget и потом вот эта вот ссылка до библиотеки. А потом, когда мы её уже один раз скачали, потом можем её либо добавлять в go файл, либо удалять при помощи утилита mode tid.

589:14

Speaker C

Прописываем. и язык программирования сам добавит нам нужные зависимости, если мы их до этого когда-то скачивали, и удалит ненужные. То есть, если мы эту библиотеку не будем использовать и напишем tidy, то опять же она просто у нас удалится из зависимости

589:30

Speaker C

за ненадобностью. Как только мы её используем и пишем Gotid, то сразу же она добавляется. Поэтому, если вы скачали какую-то библиотеку, там её используете или не используете, там новые библиотеки скачиваете, у вас почему-то не работает программа, она там не запускается, попробуйте прописать

589:47

Speaker C

Gotidy. Это может добавить к вам в зависимости библиотеки, которые вы забыли здесь прописать, либо наоборот удалить ненужные. И с помощью этого же GO TID мы можем переходить на другие версии наших зависимостей. Вот, допустим, я захотел перейти на вторую

590:01

Speaker C

версию, написал циферку два вместо три, сохранил файл. Got id. Оп, и всё, я перешёл на новую версию. Что-то там скачалось, я перешёл на новую версию.

590:12

Speaker C

Потом обратно хочу на третью. Пишу три, пишу гомойди, бам, всё, обратно перешёл на третью версию. Если выйдет какая-нибудь новая версия этой зависимости например четвёртая я также напишу четыре и напишу гомади. Ну, сейчас будет ошибка, потому что четвёртой версии, в принципе, не

590:28

Speaker C

существует. Она ещё не вышла. Вот нам говорят, что типа эта версия ещё не существует. Ну, поэтому вернёмся обратно на третью версию.

590:35

Speaker C

Модульная система программ и библиотек в Голенге позволяет очень эффективно, очень удобно управлять зависимостями. Мы можем с лёгкостью скачивать другие сторонние библиотеки, с лёгкостью их удалять, если они нам не нужны, с лёгкостью менять их версии. Это всё нам позволяет концепция модулей. Далеко не

590:53

Speaker C

во всех языках программирования существует такая удобная система по установке зависимостей. Где-то вы, в принципе, вручную должны зайти на сайт с этой библиотекой, должны скачать её исходные коды, потом должны скомпилировать в динамическую библиотеку или в статическую. И только после этого

591:11

Speaker C

влинковать, как бы на нашем языке говоря, импортировать эти скачанные библиотеки свою программу. Это всё очень долго, это очень всё странно, это неудобно. В Голенге просто пишешь go get enter, всё, у тебя скачивается это в модуль. не используешь. Написал Got

591:26

Speaker C

Tidy. У тебя модуль почистился от ненужных зависимостей. Всё просто автоматизировано. Для чего нам завязываться на какую-то конкретную версию? Ну давайте сейчас, в принципе, посмотрим, что эта библиотека умеет.

591:37

Speaker C

Называется она PP. Вот она. Нажимаем точка. И тут у нас будет такой же самый printl, как мы с вами до этого всегда использовали. Ну давайте выведем нашего юзера. Запускаем программу. И как мы видим, у нас вместо вот этого

591:51

Speaker C

непонятного вывода какие-то скобочки 530 нам вывелась конкретная структура, её название, название поля, что именно это за поле, и ещё разные цвета подключились. Ну, гораздо красивее выглядит, чем вот обычный Printn. То есть вот мы взяли с вами, установили вот

592:07

Speaker C

эту библиотеку, стали зависимы от конкретной её версии 3.0.1 и смогли использовать её функцию. Возвращаемся к вопросу, зачем нам тут какая-то конкретная версия. Потому что если в будущем разработчик вот этой вот библиотеки захочет, чтобы функция println называлась по-другому, например,

592:25

Speaker C

print prty, ну, типа красиво выведи, то мы потом в очередном запуске нашей программы обнаружим, что больше не существует функции println, потому что в новой версии её переименовали и всё, у нас программа сломается. А теперь представьте, что мы зависим от множества

592:40

Speaker C

разных библиотек, разных авторов, и нам что следить за тем, как каждый автор там что-то переименовывает, меняет какие-то названия. Нет, это неудобно. У нас постоянно наша программа будет ломаться там чуть ли не при каждом запуске, потому что кто-то что-то решил поменять.

592:53

Speaker C

Поэтому мы зависим от конкретной версии. И даже если в новых версиях автор этой библиотеки что-то там поменяет, то мы всё равно эти изменения не увидим, потому что мы будем зависе от конкретной версии, благодаря чему нам уже ничего не

593:09

Speaker C

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

593:22

Speaker C

хотим обновиться, и наш язык программирования сам скачает новую версию вот этой библиотеки. Таким образом, модули нам помогают использовать другие модули. То есть мы объявили, что наша программа - это модуль. Вот он, модуль stud. И тем самым мы смогли скачать вот эту библиотеку PP.

593:40

Speaker C

Как мы видим, у этой библиотеки тоже есть гомофайл. Так как у этой библиотеки, вот он файл, это значит, что это тоже модуль. Как вы можете видеть, тут нету никаких файлов main.go, потому что это не программа, это просто библиотека, просто

593:59

Speaker C

какой-то пакет. Вот он называется PП, и мы, собственно, этот же пакет импортируем. Но Main Go файла нет, потому что это просто библиотека. просто набор кода, набор функций, с помощью которых мы можем делать красивый вывод. Но это тоже модуль. И нам, чтобы

594:15

Speaker C

этот модуль к себе скачать, чтобы нам стать от него зависимым, чтобы мы могли выставить конкретную версию этого модуля, от которого мы зависим, нам тоже самим нужно быть модулем.

594:27

Speaker C

То есть модули - это механизм гонга, который позволяет скачивать зависимости, выставлять им нужные версии и удобно ими пользоваться. Таким образом, мы поняли, что модули нам нужны для того, чтобы скачивать сторонние зависимости и выставлять им конкретные версии. А пакеты нам нужны для того,

594:48

Speaker C

чтобы грамотно организовывать код в нашей программе. Для того, чтобы всё не сливалось в одну кучу, в одну папку. Мы можем разбивать это всё на под директории, выставлять им разные пакеты и таким образом красиво организовывать наш [музыка] код. Следующая наша тема - это массивы,

595:07

Speaker C

слайсы и мапы. Посмотрим, что это такое. Посмотрим, что такое массив, что такое слайс, что такое мапа. Обсудим то, как они устроены, и узнаем, для чего нужны.

595:18

Speaker C

Ну, первым делом давайте познакомимся с массивом. То есть, что такое массив? Ну, чисто технически говоря, массив - это последовательность значений, которые находятся в памяти непрерывно. То есть раз значение, допустим, там какая-нибудь циферка пть два значения, любая цифра, там 66, ну и

595:39

Speaker C

так далее, три значения, сколько захотим, четыре, может быть, пять. Просто последовательность значений, которые расположены в памяти непрерывно.

595:49

Speaker C

Что значит непрерывно? Значит, что если первый элемент нашей последовательности расположился на какой-то ячейке памяти, то все последующие элементы будут располагаться сразу за ним. То есть не вот так вот. Это уже не массив, это уже непонятно что, а именно последовательно,

596:10

Speaker C

именно непрерывно друг за другом. Вот такая последовательность элементов, расположенных в памяти, непрерывно называется массивом. массив может быть какого-то типа. В данном случае у нас массив целочисленных значений, там 5, 66. Ну, абсолютно любые числа можно ставить, какие мы захотим.

596:32

Speaker C

100. Ну и там единичка просто. Вот это массив целочисленных значений. Почему массив? Потому что это последовательность каких-то элементов, которые расположены в памяти непрерывно.

596:43

Speaker C

Собственно, это и есть массив. Пока что непонятно, зачем нам вообще это нужно. Мы же по сути можем пять отдельных переменных создать для этого. Зачем нам это как-то объединять в какой-то там массив? Это мы разберём чуть позже.

596:56

Speaker C

Сейчас нам необходимо рассмотреть, как это устроено с технической точки зрения. А с технической точки зрения мы поняли, что массив - это последовательность элементов, последовательность каких-то значений, которые расположены в памяти непрерывно, друг за дружкой. Давайте посмотрим, как бы этот массив у нас

597:14

Speaker C

выглядел в нашем коде. Ну вот, я открыл редактор кода. Давайте дополнительно на схеме для больше ясности я выделю наш массив вот таким вот оранжевым прямоугольничком, чтобы мы понимали, что это не просто какие-то отдельные пять целочисленных переменных, а что это

597:32

Speaker C

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

597:50

Speaker C

- это тоже отдельная переменная, просто новый тип. До этого мы с вами проходили целые числа, дробные числа, строки, структуры. Так вот, массив - это тоже переменная, и её мы назовём R. То есть R - это сокращение от array, а array - это

598:07

Speaker C

с английского массив. Поэтому я назову его R. Для того, чтобы создать массив Голенге, нужно указать тип массива. То есть массивы могут быть разных типов.

598:16

Speaker C

Целочисленный массив, массив строковых значений, массив каких-то структур, массив чего угодно у нас может быть. И все элементы в этом массиве будут иметь одинаковый тип. То есть невозможно создать такой массив. Нету возможности, чтобы один элемент был целым числом, а

598:34

Speaker C

другой элемент был строкой. То есть все элементы массива должны иметь один и тот же тип с некоторыми оговорками, но пока для нас это так. И вот создаём массив.

598:44

Speaker C

То есть в переменную array мы будем класть массив. Синтаксис объявления массива следующий. Мы ставим квадратные скобочки. И в этих скобочках мы пишем, сколько у нас будет элементов в этом массиве. Ну, в данном случае у нас пять элементов, поэтому пишем циферку пять.

599:01

Speaker C

После этого нам нужно написать, какой тип будет у этих значений. В нашем случае это int. И потом в фигурных скобочках мы через запятую должны все эти значения перечислить. Первое у нас пть, второе 66, потом 7, потом 100, потом один. Всё, мы с вами создали

599:20

Speaker C

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

599:38

Speaker C

пять чисел через пробельчик были выведены на экран. Ну и чтобы нам понять, что это принадлежность к какому-то отдельному массиву, они вот заключены в такие квадратные скобочки.

599:48

Speaker C

Поздравляю, мы с вами создали массив. Что мы можем делать с массивом? Мы можем получать доступ к отдельным его элементам. Допустим, я хочу вывести 66.

599:58

Speaker C

Я просто беру и обращаюсь к этому элементу. Смотрите, нумерация элементов в массиве начинается не с одного, как мы все могли подумать, что тут вот 1 2 3 4 5 Нет, нумерация на самом деле начинается с нуля. То есть это нулевой

600:19

Speaker C

элемент, это первый элемент, это второй элемент, это третий элемент, это четвёртый элемент. именно с нуля, не с единицы, а с нуля. Почему так странно?

600:30

Speaker C

На самом деле причины этому уходят глубоко в корни, вообще в истомирования, когда активно использовалось тесное взаимодействие с памятью, и поэтому массивы начинали свою нумерацию именно с нуля. Сейчас я не буду вдаваться в такие подробности, потому что это лишь запутает. Если кому

600:50

Speaker C

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

601:03

Speaker C

Соответственно, это нулевой элемент. Это первый, это второй, это третий, это четвёртый. И нам предоставлена возможность отдельно взаимодействовать с каждым из этих значений. Ну, допустим, я могу вывести на экран первый элемент, то есть 66. Я для этого пишу название

601:20

Speaker C

нашего массива и в квадратных скобочках передаю номер элемента, который я хочу вывести. Номер элемента, к которому я хочу обратиться. Запускаю программу и вижу, что вывелось 66. Также я могу отдельно какому-то элементу массива прибавить какое-то значение. Ну, допустим, я этому же R с индексом один,

601:40

Speaker C

то есть это называется индекс номер. Ну или с программистского языка индекс. R с индексом один я хочу прибавить пятёрку. Всё, я беру наш массив. Я говорю, что в этом массиве я хочу к первому элементу прибавить пять. Ну и

601:57

Speaker C

давайте выведем заново этот первый элемент. И как мы видим, было 66, стало 71. То есть я просто взял и к этому элементу прибавил пятёрку. Отдельно взял элемент из памяти, отдельное значение и прибавил туда пятёрочку. Давайте после этого выведем весь массив на экран.

602:17

Speaker C

Вот видим именно у нашего первого элемента. До этого у нас там 66 было, после этого стало 71. Можно вычитать, умножать, что угодно делать. Что будет, если я попытаюсь взять какой-то элемент, которого нету у нас в массиве? Ну, допустим, я захочу взять пятый элемент.

602:34

Speaker C

То есть у нас их всего четыре. 0 1 2 3 4, а я захочу взять пятый, ну, которого нету на самом деле, и вывести его на экран. Давайте посмотрим, что будет.

602:44

Speaker C

Запускаю программу. И мне пишет, что индекс 5 out of bounce. Что это значит? Значит, индекс 5 вышел за границы. То есть я, обращаясь вот к этому вот массивчику, который я выделил оранжевым, захотел взять какой-то элемент, который лежит за его пределами. И мне выдало

603:02

Speaker C

ошибку, потому что там ничего не лежит. Мы эту память с вами вообще ещё никак не использовали. То есть доступ к этой памяти, в принципе, может быть опасен, потому что мы там можем что-нибудь напортачить, что-нибудь туда положить, какое-то значение. А если эта ячейка

603:15

Speaker C

памяти используется операционной системой, что мы на винде синей кран смерти получим? Ну нет, нельзя. Если выделил массив на пять элементов, то и работай в рамках этого массива на пять элементов. За границей этого массива доступ запрещён. Поэтому мы получаем

603:30

Speaker C

ошибку, что мы попытались обратиться вот к этому элементу. Ну а как бы мы его вообще никак для себя не выделяли. Это за границами нашего массива. Поэтому получили следующую ошибку.

603:42

Speaker C

Нам даже редактор кода подчёркивает, что как бы у нас будет эта самая ошибка. Ну а работать в рамках массива можно.

603:48

Speaker C

Давайте выведем последовательно все элементы. Ар с индексом [аплодисменты] ноль. И вот так вот 1 2 3 4 и буду выводить ещё вот так вот дополнительно их индексы, чтобы было понятно, что именно за элемент мы выводим. Сохраняю, запускаю программу.

604:13

Speaker C

Ну и мы видим, что у нас нулевой элемент - это пть, первый элемент - это 66.

604:20

Speaker C

Второй элемент - это се, третий элемент - это 100. И четвёртый элемент - это у нас один. Таким образом, мы можем выводить массив на экран, просто взять и перебрать все его значения. Повторюсь, мы можем сюда класть какие-то значения,

604:34

Speaker C

их там прибавлять, умножать, делить. У нас просто массив целых чисел. И с каждым отдельным элементом этого массива мы можем работать как с отдельной переменной. То есть мы просто взяли и несколько целочисленных значений объединили в одну переменную. И теперь

604:51

Speaker C

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

605:03

Speaker C

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

605:20

Speaker C

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

605:28

Speaker C

Почему? Потому что ячейка памяти, которая идёт сразу же за массивом, может быть уже занята или другой программой, или операционной системой, или чем бы то ни было ещё. Поэтому мы не можем гарантировать, что просто вот так вот взять наш массив и увеличить его на

605:44

Speaker C

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

606:04

Speaker C

размером на один побольше. Мы берём эту область памяти, выделяем, потом все элементы из старого массива мы туда перекопируем, переносим. Вот перенесли все элементы. И потом только мы можем добавить ещё один элемент и положить туда какое-нибудь значение, которое мы хотим. Ну, там,

606:25

Speaker C

допустим, 77 пускай лежит. Вот. О'кей. Увеличили массив на один. А теперь мы хотим ещё на один его увеличить. О, пошла жара. Опять нужно найти где-то свободное место в памяти, которое больше, чем наш текущий массив на единичку. Занять это место в памяти,

606:43

Speaker C

перегнать туда все элементы и в конце добавить в лишний слот наш новый элемент. Это всё на самом-то деле не очень удобно, поэтому массивы в привычном их понимании, вот такие вот, которые заданным размером, их используют довольно редко. Ну, ещё это называется

607:01

Speaker C

статический массив. Почему статический? Ну, потому что у него строго заданный размер, который мы не можем менять.

607:06

Speaker C

Допустим, опять же, мы по ходу выполнения нашей программы поняли, что нам нужен ещё один массив, который больше, чем R на1, но назову его R2. Для этого нам нужно сначала выделить шесть ячеек в оперативной памяти, потом перекопировать наш старый массив в

607:23

Speaker C

новый, то есть в новый массив нулевой элемент. Мы кладём нулевой элемент из старого массива. И так нам нужно для всех пяти. То есть в первый мы кладём первый, во второй - второй, в третий третий, в четвёртый четвёртый. Перекопировали. И теперь у

607:44

Speaker C

нас появилась возможность в пятый элемент, то есть вот сюда вот ещё в пятый элемент положить что-то R2 вот с индексом 5 мы сюда можем что-нибудь положить там вот наше же 77. И теперь, в принципе, можем вывести это R2 на

608:08

Speaker C

экран. Сохраняем, запускаем. Ну и вот наш R2. Ну, для наглядности давайте наш старый массив выведем, который просто R называется. Запускаем. Ну и видим, что у нас R2 - это тот же самый R1, только с одним элементиком дополнительно.

608:28

Speaker C

Повторюсь, почему мы не могли в старый массив просто докинуть какой-то элемент? Потому что в оперативной памяти нам бы пришлось взять и внаглую вот этот наш массив вот так вот увеличить. А мы этого сделать не могли, потому что следующая

608:41

Speaker C

за последним элементом ячейка памяти могла быть уже кем-то зарезервирована. И мы не можем безопасно вот так вот поступать. Мы не можем безопасно брать какие-то рандомные ячейки в оперативной памяти. Нам нужно сначала найти пространство в оперативной памяти, которое бы было свободно полностью и

609:00

Speaker C

никем не зарезервировано. После этого его зарезервировать, перекидать туда старые значения. И в конце мы бы могли добавить вот наше новенькое значение.

609:10

Speaker C

Это неудобно, как бы, да. Поэтому обычные статические массивы используются довольно редко, их не часто можно встретить в настоящем коде. Но тем не менее для общего понимания тема массивы крайне важна. Именно в коде они встречаются редко, но в более сложных

609:27

Speaker C

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

609:45

Speaker C

массива. Индексация массива начинается с нуля. Почему так? Потому что исторически сложилось. И если очень глубоко под капот залезть, то можно понять, почему это именно так работает. Могу сейчас просто вкратце сказать, если вы ничего не поймёте, ничего страшного. Короче, по

610:02

Speaker C

сути, массив ещё со времён языка C - это был адрес самой первой ячейки в этом массиве. И чтобы получить значение в этой самой первой ячейке массива, нужно было к этому адресу добавить ноль. Ну, потому что этот адрес плюс 0 равно тот

610:15

Speaker C

же самый адрес, и мы получали эту переменную. Этот адрес + О, мы получали следующую переменную. Этот адрес + 2 мы получали вот эту переменную. Поэтому индексация, номер самого первого элемента был ноль, потому что его адрес п 0 - это он же сам. Этот адрес п - это

610:34

Speaker C

уже следующая переменная. Вот она. Поэтому такая индексация. Ну и как бы уже никто ничего менять не стал. Вот она вот так вот до наших времён идёт. И нам с этим остаётся только лишь смириться.

610:44

Speaker C

Что ещё мы можем делать с массивами? Ну, вообще, работа с массивами чаще всего осуществляется при помощи циклов.

610:51

Speaker C

Почему? Потому что мы можем описать алгоритм, который бы что-то делал с одним элементом, и при этом в цикле прогнать для каждого элемента этот алгоритм и получить прогон по всему массиву. Ну давайте я вот это вот сотру. И предположим, перед нами задача,

611:11

Speaker C

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

611:32

Speaker C

здесь вот значение поменяет и скажет: "А теперь и нам придётся всё заново делать". Нет, нам нужно именно с помощью кода это сделать. Ну, смотрим, если нулевой элемент процент 2 = 0, то есть если нулевой элемент у нас чётный, тогда

611:45

Speaker C

этот нулевой элемент мы умножаем на два. И то же самое мы бы делали со всеми остальными элементами. То есть вот с первым элементом, со вторым элементом, с третьим элементом и с четвёртым элементом. Вот. Ну и, соответственно, у нас это нечётное. Вот 66 чётное, оно

612:14

Speaker C

умножится на 2 и станет у нас 132. Семь нечётное, 100 чётное, оно умножится на 2 и станет равно 200. Вот смотрите, как я использую многосрочный комментарий, чтобы в рамках строчки подкомментировать несколько символов. Ну и, соответственно, у нас изменится

612:34

Speaker C

только первый элемент и третий. Давайте запустим нашу программу. Ну и мы увидим, да, что у нас все значения остались как были. Кроме первого, потому что 66 - это чётное, и кроме предпоследнего оно тоже удвоилось.

612:49

Speaker C

А теперь представим, что у нас в массиве есть 100 элементов. Ну, это стандартная ситуация. Или 500, или 1.000. И что нам 1.000 строк кода писать? Да нет, мы можем увидеть, что у нас всё, что тут отличается в обработке каждого

613:01

Speaker C

отдельного элемента- это циферка. Тут нолик, тут единичка, тут двоечка, тут троечка, тут четвёрочка. И если у нас будет там 100 млн элементов в массиве, всё равно всё, что будет отличаться от элемента к элементу, это циферка. Там будет 100.000, 100.0001, 100.0002. Мы

613:18

Speaker C

можем это всё сделать с помощью цикла. Каким образом? Сейчас напишу код, потом объясню, что вообще произошло.

613:24

Speaker C

4 i = 0 i < 5 i + Ну, мы обычно начинали i с единицы, но так как у нас нумерация с вами начинается с нуля, поэтому мы i сначала присваиваем ноль. Ну и меньше пти, то есть так как мы не хотим выйти за

613:43

Speaker C

границы массива, да, мы не хотим случайно обратиться к элементу, которого у нас нету, то мы ограничиваем наше i меньше пяти. То есть четыре нам ещё подходит. А вот пять уже не подходит, потому что у нас самый большой индекс

613:58

Speaker C

валидный - это вот четыре. Ну и, соответственно, мы будем смотреть, что если у нас массив не с индексом каким-то конкретным, а с индексом i процент 2 = 0, тогда массив с этим индексом мы умножаем на 2. Это всё можно стереть.

614:21

Speaker C

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

614:33

Speaker C

Ну и как видим, да, действительно, умножаются наши с вами элементы. Что тут вообще произошло? Мы создали цикл, то есть переменная а изначально равна нулю.

614:42

Speaker C

Мы будем проводить цикл, проводить итерации до тех пор, пока i меньше п и на каждой итерации прибавлять1. Ну и смотрим, на первой итерации у нас i0. И тут выполнится этот код, возьмётся массив с индексом ноль, то есть нулевой

614:58

Speaker C

элемент. Пятёрочка. Пятёрочка процент 2 = 0. Ну пятёрочка чётная. Нет, ну тогда ничего не выполнится. Потом у нас i + i стала уже единичкой равно. И мы опять прогоняем вот этот вот код. Смотрим.

615:11

Speaker C

Если массив с индексом один, то есть, массив с индексом один чётный, вот он массив с индексом 1, 66, да, чётный.

615:19

Speaker C

Значит, проваливаемся в этот блок, и мы массив с индексом 1 умножим на 2. Всё, вот он 132. 66 на 2 132. Потом i+ опять у нас делает i становится двум равно.

615:32

Speaker C

Массив с индексом 2 чётный. Нет, ничего не произошло. I+ п+ I у нас стала троечкой.

615:41

Speaker C

Массив с индексом 3 чётный, да? 100. 100 у 2, получается 200. I + п+ у нас а стало равно 4. 4 меньше п. Да, продолжаем. Массив с индексом 4 чётный. Нет, ничего не произошло. I + I стала равно 5. Пти 5 меньше п нет. Всё,

616:03

Speaker C

заканчивается цикл. Вывод на экран. Таким же самым образом с помощью цикла мы можем выводить весь массив. Ну, мы, конечно, можем его вывести с помощью одного принтана. Вот так вот просто, но он выводится как-то странно, там в скобочках не очень красиво. Мы

616:20

Speaker C

можем выводить его просто с помощью цикла. Для этого делаю точно такой же цикл с точно такой же итерацией по каждому элементу. Поэтому I у нас от нуля до пяти, не включительно пять. И на каждой итерации я просто буду

616:38

Speaker C

выводить индекс элемента. Потом через тире буду выводить значение элемента с этим индексом. Это могу стереть. Сохраняю. Запускаю. Всё.

616:52

Speaker C

Нулевой индекс у нас пять. Первый индекс 132, потому что до этого он в этом цикле был умножен 7 200. И четвёртый индекс у нас равен единице. Таким образом, мы опять же готовы теперь работать с абсолютно любой длиной этого массива.

617:11

Speaker C

Будь тут сем, например, да? Вот у нас в конце было бы 2,4. Только теперь нам нужно проходиться не до пяти, а проходиться до семи. Семь элементов теперь в массиве.

617:22

Speaker C

Нам нужно до семи проходиться. Запускаем. И вот видим то же самое. Мы теперь выводим наш массив полностью. Мы полностью проходимся этим алгоритмом. В конце он двойку и четвёрку умножили на два, получили 4,8. Потом вывели всё это на экран ещё. И всё это благодаря одним

617:38

Speaker C

и тем же циклам. Просто одну циферку можно менять. То есть благодаря тому, что у нас все эти значения находятся не в разных переменных, а благодаря тому, что они у нас объединены в один массив, мы можем с помощью циклов проводить над

617:54

Speaker C

ними операции сразу же, как над целой группой. не отдельно вот эти вот кусочки кода писать для каждой переменной, а просто в цикле этот кусок кода написать и потом ко всему массиву применить. Вот массивы в связке с циклами используются

618:10

Speaker C

очень часто, потому что мы можем набить массив каких-то значений, а потом производить над целым массивом этих значений какие-то операции. Ну, давайте рассмотрим уже на каком-то более осмысленном примере, потому что пока не очень понятно, зачем нам все циферки чётные умножать на два. Давайте

618:28

Speaker C

представим, что мы также разрабатываем нашу социальную сеть, и у нас есть структура пользователя. У пользователя есть имя строкового типа, и у пользователя есть какой-то социальный рейтинг дробного типа. Также пользователь имеет возможность приобретать премиум аккаунт. То есть пользователь может быть

618:48

Speaker C

премиумом, а может не быть премиумом. То есть как в Телеграме у нас мы можем купить премиум аккаунт, и тогда у нас вот эта переменная премиум станет true.

618:56

Speaker C

То есть, да, он купил премиум аккаунт. Если переменная премиум у нас флс, значит, пользователь не купил премиум аккаунт. Значит, он не премиум, а обычный. Теперь, допустим, перед нами задача. У нас есть какое-то количество этих юзеров. Давайте я вот это всё

619:10

Speaker C

сотру. У нас есть какое-то количество юзеров. Юзер один. [аплодисменты] Его имя будет там Данил, рейтинг 5 с поно премиум. То есть, да, он как бы премиумюр. У нас есть второй [аплодисменты] пользователь. Имя у него пускай будет Петя. Рейтинг 4 с по премиум FSE, то

619:37

Speaker C

есть он не премиум. Ну и третьего пользователя создадим. Имя у него будет Вайся. рейтинг 7 с по и премиум true, то есть, да, премиум. Вот у нас есть три пользователя. Из них Данил и Вася премиум, а Петя у нас не премиум. Вот

619:55

Speaker C

премиумфSE. И теперь к нам приходит наш начальник и говорит, что, короче, я хочу запустить акцию, что у всех, у кого есть премиум аккаунт, тому социальный рейтинг, мы прибавляем единицу. И мы такие: "Ага, о'кей, берём и первому юзеру, если у него премиум, то есть если

620:16

Speaker C

у юзера один премиум, тогда мы ему рейтинг прибавим единичку". Также, если у нас usеer 2 премиум аккаунт купил, тогда мы ему тоже прибавим единичку рейтинга. Ну и с юзером 3, в принципе, то же самое.

620:39

Speaker C

Сразу скажу, что заранее мы не знаем, премиум у них или нет. Предположим, у нас множество пользователей, они все хранятся в базе данных. У нас там типа очень много пользователей, может быть, миллионы. Мы не можем у каждого посмотреть, премиум он или нет. Нам

620:52

Speaker C

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

621:08

Speaker C

нашего бонусного и после. Для этого я, кстати, хочу использовать библиотеку из предыдущего урока для красивого вывода структур. Ну, для того, чтобы нам подключить какую-то стороннюю библиотеку, а библиотека сторонняя - это модуль, нам тоже самим нужно стать модулем. Поэтому я сделаю модуль go

621:24

Speaker C

init. Ну, стади его также назову, там неважно, как мы его назовём. И теперь захочу подключить ту самую библиотеку.

621:31

Speaker C

Нахожу её на гитхабе. Копирую ссылку. И после создания модуля пишу go get и эту самую библиотеку.

621:40

Speaker C

Enter. Всё скачалось и добавилось. Теперь могу её использовать. PP тоprintln. Вот редактор кода мне сам подключил эту библиотеку. Ну, потому что я создал модуль и скачал её. Теперь, когда я буду её прописывать, то он позволит мне её автоматически

621:58

Speaker C

импортировать. Вот я создал трёх пользователей, вывел их до, то есть до чёрточки и потом эти три юзера. 1раз 1 2три. Ну и в конце ещё пустую строчку для разделения. Потом провёл наш алгоритм применения бонусов и вывожу пользователей после. Запускаю

622:16

Speaker C

программу. Ну и вижу, что вот до у меня Данил с премиумом и Вася с премиумом.

622:23

Speaker C

Петя у меня без премиума. И, соответственно, у Пет был рейтинг 4 с поно, он 4 с поно и остался. У Данила был 5 с поно, стал 6 с поно, потому что у него премиум прибавилась единица. Ну и у Васи тоже

622:37

Speaker C

был премиум, было 7,5, стало 8,5, потому что премиум. Вроде всё работает круто. Но теперь, предположим, у нас наша социальная сеть жёстко хайпанула, да, у неё теперь стало там не три пользователя, а 30.000 пользователей.

622:51

Speaker C

А нам нужно поддерживать вот этот вот код, который у нас обрабатывает бонусный рейтинг для премиум юзеров. Ну что нам теперь нужно? Вот так копировать и писать user 4, создавать его в нашем коде, применять к нему рейтинг. И что? И так все 30.000

623:08

Speaker C

делать. Ну это такое себе. А вспоминаем, что мы только что с вами прошли массивы.

623:14

Speaker C

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

623:31

Speaker C

алгоритм, мы можем запихнуть этих юзеров массив и циклом пробежаться. Так, давайте это и сделаем. Я назову это user array. User array у нас имеет размер три и тип usеer. То есть у нас массив юзеров. Я могу в этот массив сразу же положить

623:48

Speaker C

копии вот этих вот значений, просто написав usеer 1, user 2 и user 3. То есть, повторюсь, здесь мы кладём не указатели, а значит, происходит то же самое, что и при передаче в аргументы функции. Тут значения просто скопируются. То есть мы имеем три

624:04

Speaker C

отдельные переменные в памяти. Вот у нас usеer 1, user 2, вот user 3. Вот он usеer 1, user 2, user 3. Просто три отдельные переменные. Это никакой не массив, три отдельные переменные. Потом в тридцать четвёртой строчке мы создаём

624:18

Speaker C

массив из трёх юзеров и копируем в него значение usеer 1, user 2, user 3. То есть мы просто создаём отдельный массив.

624:26

Speaker C

И вот эти вот значения usеer 1, user 2, user 3, мы их туда копируем.

624:32

Speaker C

Получается, если мы в массиве изменим какие-то элементы, то оригинальные юзеры у нас не изменятся, да? У нас изменятся только вот эти вот значения в массиве, потому что мы будем менять вот эти вот скопированные значения. Оригинальные переменные это не затронет. Как бы как

624:46

Speaker C

нам выйдет тут из ситуации? можно как-то очень выпендриться, там что-то указатели как-то пытаться прокинуть, а можем просто создавать этих юзеров сразу же внутри нашего массива, благодаря чему у нас будет, так сказать, один источник правды. То есть мы просто берём и вместо этих переменных

625:05

Speaker C

вот так вот будем копировать тут создание юзера. О, скопировали, usзеер 2 скопировали и вот usеer 3 скопировали. Это я удаляю.

625:16

Speaker C

Всё, теперь у нас один источник правды - это наш массив. Теперь вот этих юзеров у нас нету, просто массив юзеров. Всё удобно. Меняем в массиве и всё, больше нигде менять не нужно. Теперь у нас есть массив наших юзеров. Мы вот их создали

625:29

Speaker C

прямо здесь, прямо на месте. Прямо при создании массива мы создали ещё и каждого отдельного юзера. Задали каждое значение для каждого элемента массива usеer. Ну теперь можем вывести до, опять же, до, если у нас массив будет 30.000.

625:44

Speaker C

Ну, поэтому тут циклом лучше всего вывести. Просто пробегаемся по каждому элементу массива. У нас вот массив размерностью три. Значит, самый большой его индекс будет 2 0 1 и 2. И поэтому нам нужно, чтобы iло меньше тёх, то есть

626:00

Speaker C

2. Когда i станет 3, то это условие уже не выполнится, и у нас цикл закончится.

626:06

Speaker C

I++. Ну и тут везде я просто буду выводить user array с индексом i. И всё.

626:13

Speaker C

Вот это наш вывод до и то же самое после. А теперь в цикле напишем алгоритм наш обработки юзеров. Точно так же I = 0, I 3, I++. Ну и берём просто и тут вместо конкретного какого-то юзера мы берём индекс у нашего

626:38

Speaker C

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

626:53

Speaker C

давайте запустим нашу программу. Ну и как мы видим, до Данил 5,5, Вася 7,5, после к Данилу одна прибавилась единица рейтинга и к Васе.

627:05

Speaker C

Ну а к Пет не прибавилось, потому что у него нету премиума. Всё мы просто берём.

627:09

Speaker C

I. И для каждого из этих юзеров, для каждого элемента в нашем массиве мы прогоняем вот этот вот алгоритм в цикле.

627:17

Speaker C

Смотрим, что у нас usеer array очередной элемент из этого массива. То есть очередной usеer премиум. Если да, то прибавляем рейтинг, если нет, то ничего не делаем. Всё. Теперь давайте чуть-чуть поговорим о том, как можно наш код улучшить, какие есть для этого

627:32

Speaker C

возможности в голенге. Ну, во-первых, мы можем каждый раз не проверять здесь руками, какая длина у нашего массива. То есть тут нам постоянно нужно смотреть.

627:39

Speaker C

Ага, три, значит, три там. Ага, там было бы тут 39, нам бы вот тут вот везде нужно было писать 39. Это не очень удобно. Мы можем с помощью кода получать длину массива.

627:52

Speaker C

Как это выглядит? Просто пишем lен и в скобочке наш массив. Что тут случилось? Когда мы наш массив передаём в функцию lенen, len - это встроенная в язык программирования функции. Мы её как бы нигде не видим, но она встроенная в язык

628:05

Speaker C

программирования. Она где-то есть, как говорится. Ты видишь функцию нет, а она есть. Передаём туда наш массив. И возвращает она integer, то есть возвращает просто длину массива. И мы можем везде опираться не на литерал, который мы руками пишем, а на результат

628:21

Speaker C

выполнения функции lенen. Len - это с английского lens, то есть длина. Всё. Теперь мы везде зависим от длины массива. И если у нас длина массива будет три, как в данном случае, то i будет меньше т. Ну, нас это

628:37

Speaker C

устраивает. Если длина массива будет 30.000, I будет меньше 30.000. И всё. И мы никогда не выйдем за границы массива.

628:44

Speaker C

То есть вот в нашем примере, когда у нас три элемента, вот, допустим, длина массива у нас три. Длина массива три 1 2 3. Len возвращает 3. Получается I будет от нуля до тёх. Три не включительно, потому что у нас будет два. Выведится

628:58

Speaker C

последний элемент плюс плюс I станет три. 3 меньше тх нет. Всё. И мы вот уже в этот элемент не залезем. В элемент с индексом 3 мы не залезем, потому что он уже за гранью нашего массива. Мы остановимся на элементе с индексом два.

629:12

Speaker C

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

629:29

Speaker C

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

629:38

Speaker C

Пускай у нас ещё будет Игорь и Сергей. Ну и у них будет у Игоря рейтинг 1,5, у Сергея рейтинг 2.3. У Игоря есть премиум, у Сергея нету премиума. Всё, мы просто взяли, добавили юзеров, чуть подкорректировали наш массив, запускаем

629:58

Speaker C

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

630:04

Speaker C

Потому что наш код уже адаптирован под работу с массивами, и какой бы массив мы в него не передали, он будет выводить ровно столько элементов, сколько есть в массиве, отдавая должное внимание каждому отдельному элементу. Ну вот у нас рейтинги до. В принципе, Данила

630:20

Speaker C

Петювасю мы разобрали. Вот Игорь Сергей. То есть у Игоря есть премиум, у него должно стать 2 сно. У Сергея премиума нету, у него должно остаться 2,3. 2 с 2,3. Всё работает у нас. И вывод доработает корректно. И вывод после

630:35

Speaker C

работает корректно, и сам алгоритм бонусного рейтинга работает корректно. Но при этом вот этот вот наш кусок кода от входящего массива вообще не меняется.

630:46

Speaker C

Да будь тут хоть 30.000 элементов, вот этот вот наш код останется прежним. В этом и основное назначение массивов. Для чего они вообще используются? для того, чтобы объединить какие-то сущности в один набор данных, в один набор значений и потом каким-то универсальным кодом,

631:06

Speaker C

чаще всего это именно циклы, пройтись по этому набору значений и что-то с ними сделать. Ну, в данном случае у нас проверить, что usеer premium добавить рейтинга. Что ещё есть в языке программирования для удобной работы с массивами? Ну, вообще циклф можно писать

631:22

Speaker C

немножко по-другому. То есть тут мы его писали в таком олдскуле, когда мы сами создаём вот эту переменную i, сами её перебираем, прибавляем, смотрим за её значением, чтобы не выйти за концы массива. Это прямо такая старая школа.

631:36

Speaker C

Теперь давайте посмотрим, как это может выглядеть на более современный лад. Опять же напишу код, потом объясню, что я вообще написал. Вот я написал тоже цикл, но выглядит он прямо, ну, совсем как-то странно, да. Вот закомментировал старый цикл. Что тут произошло? Я сказал

631:52

Speaker C

языку программирования, что пройдись по всему массиву и на каждой итерации давай мне индекс и значение очередного элемента.

632:02

Speaker C

А, тоже не очень понятно. Давайте смотреть подробнее. Вот у нас есть массив наш, да, usеer array из пяти элементов. Давайте для удобства пока сократим его до трёх элементов. Вот массив из трёх элементов. Мы проходимся по нему и говорим нашему циклу, что,

632:16

Speaker C

короче, я хочу замутить цикл, который будет пробегаться по массиву. То есть range - это значит пробегись, типа, пройди дистанцию, пробеги по массиву, то есть пробеги по каждому элементу, по первому, по второму, по третьему. И для каждого отдельного элемента запускай

632:32

Speaker C

новую итерацию и возвращай мне индекс этого элемента и его значения. То есть вот это переменные, которые мы создаём, и мы можем их назвать как угодно. Можно назвать это индекс, а это назвать user.

632:45

Speaker C

Можно назвать это IV, что значит index value, типа value значение. Ну, давайте для большей наглядности назову это индекс, а это назову user. И будем выводить на экран идекс и usе. То есть я говорю сделай пожалуйста цикл который будет пробегаться по всему

633:05

Speaker C

userrрею. И для каждого элемента отдельного в этом массиве запускай отдельную итерацию и на каждой итерации в переменную индекс и переменную usеer клади значение индекса рассматриваемого элемента и его значения. Всё. То есть я буду пробегаться по каждому юзеру.

633:23

Speaker C

Возьму сначала usр 1, мне вернётся индекс ноль и вот это вот значение. Потом итерация закончится, мне вернётся индекс один и вот это значение. В чём преимущество вот такого вида циклов по сравнению с тем, что мы рассматривали до этого? В том, что нам уже не нужно

633:38

Speaker C

следить за тем, какая длина у этого массива, нам не нужно вручную прибавлять вот эту вот переменную. Мы можем просто сказать, что язык программирования, короче, хочу по всему массиву пробежаться, сделаю по красоте. И всё.

633:50

Speaker C

Может быть такая ситуация, когда нам, в принципе, не нужен индекс, да, когда мы только значение хотим получить. Просто пробежаться по значениям. Тогда мы можем заместо индекса написать нижнее подчёркивание и всё. И нам тогда будут даны только значения каждого элемента в

634:07

Speaker C

массиве. И на каждое вот это значение будет запущена отдельная итерация. Ну давайте тут мы будем использовать индекс. Верну размер нашего массива на три. Запускаем программу. Ну и видим, что вот у нас до индекс значение, как мы с вами и выводили индекс, потом значение

634:24

Speaker C

индекс ноль значение такое. Вот у нас ноль Данил рейтинг 5 сно индекс 1 значение индекс 2 значение всё мы таким образом запустили цикл, где на каждой итерации просто автоматически нам возвращается индекс и значение каждого очередного элемента в массиве. Нам уже

634:43

Speaker C

не нужно следить за переменной а и что-то там её прибавлять. Оно вот всё автоматически происходит. Теперь давайте воспользуемся этим в нашем премиум алгоритме. В нашем алгоритме начисления премиума. Ну вот, закомментирую старый код. И казалось бы, всё просто. С

634:56

Speaker C

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

635:14

Speaker C

нижнее подчёркивание поставить и всё. Давайте запустим, посмотрим. Как мы видим, что вот Вася у нас рейтинг 7 с попремиум и осталось 7 с поно. Почему?

635:26

Speaker C

Потому что когда мы используем вот такой формат цикла, то у нас на каждую итерацию вот в эти переменные кладётся копия наших значений. Что это значит?

635:36

Speaker C

Что на каждую итерацию создаётся новая переменная usеer, в неё кладётся очередное значение и мы работаем с этим значением.

635:46

Speaker C

То есть тут внутри цикла, поменяв переменную usеer, мы поменяли копию. То есть на каждой отдельной итерации создавалась копия, с которой мы работали. И мы вот тут вот на очередной итерации поменяли эту копию. Но на исходный массив это никакого влияния не

636:01

Speaker C

оказало. Поэтому нужно быть внимательным с этими усовершенствованными циклами. Это, как говорится, с большой силой приходит большая ответственность. Нужно чётко понимать, что происходит в вашей программе. Поэтому тут, когда мы хотим с помощью нового цикла пробежаться по всему массиву и изменить не копию вот

636:18

Speaker C

эту вот, не копию, которая вот тут вотту создаётся на каждой итерации, а именно наш user array, элементы в нём, нам нужно хранить этот самый индекс и менять уже не копию вот эту вот, а именно исходный массив с индексом.

636:38

Speaker C

[аплодисменты] запускаем и видим, что Вася у нас стал 8 с по был 7 с по с премиумом, стал 8 с по всё работает. Тут уже начинается, как обычно усмотрение программиста, усмотрение разработчика. Если разработчик хочет использовать олдстайл циклы для таких вот прогонов и изменений

636:59

Speaker C

элементов, это не возброняется. Хорошо, пускай используют эти старые циклы. Если разработчик хочет использовать новые циклы, то он должен чётко понимать, что они очень хорошо подходят для того, чтобы просто получить каждый элементик и вывести его на экран, например. Но они

637:15

Speaker C

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

637:33

Speaker C

и менять. То есть, несмотря на то, что здесь у нас на каждой итерации в юзер кладётся копия, мы по этой копии смотрим премиумстатус, но меняем мы уже не копию, то есть не usеer rйтиting п = 1. Вот эта вот копия наша.

637:52

Speaker C

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

638:06

Speaker C

копии обойтись, как бы, да, и тут вот смотреть user array index топ premium, то есть сразу же с помощью вот этого индекса, который нам даётся, вообще на эту копию не смотреть, просто сразу же в исходный массив смотреть и менять исходный

638:21

Speaker C

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

638:27

Speaker C

Ну да, хорошо, нижнее подчёркивание ставим, всё, она не создаётся. Ну тут, в принципе, уже и теряется весь смысл этих наших навороченных циклов. Вот, в принципе, по старому образцу было бы гораздо более понятно. Мы сразу видим, что создаём переменную I. Мы бежим этим

638:44

Speaker C

I по всему массиву. И массив с этим I, с этим индексом мы меняем и проверяем. Но тут как кому удобно, опять же, на вкус и цвет. И то хорошо, и то хорошо. Главное понимать, что именно происходит в циклах, что именно происходит на каждой

638:57

Speaker C

итерации. Ну и давайте вывод, который у нас после, я тоже переведу на новый лад.

639:01

Speaker C

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

639:20

Speaker C

Мне как бы пофигу, если честно, какого он там индекса. Поэтому я просто, что в первом случае, что во втором случае, заместо индекса поставлю нижнее подчёркивание, чтобы только юзеров выводить. Сохраняю, запускаю. Ну и всё, до и после. Как мы видим, у вас Данил с

639:36

Speaker C

премиумом 5 с стал 6 с5. Вайся с премиумом был 7, по стал 8 с по. Ну и Петя без премиума, как был 4 с5, так и остался. Всё. Теперь мы можем, как обычно, докидывать элементы в наш массивчик и выводить их на экран,

639:50

Speaker C

применять наши вот эти алгоритмы. Казалось бы, такая замечательная вещь, как массивы, почему её используют редко?

639:57

Speaker C

Да всё просто. Один из самых больших минусов массивов - это то, что он статический. Если мы создали где-то в коде массив на три элемента, он будет три элемента дальше везде, во всей программе. Если мы вдруг захотим добавить сюда очередной элемент, нам

640:12

Speaker C

придётся где-то в коде создавать новый массив размером четыре и перекидывать туда все вот эти вот значения, перекопировать, и только потом мы сможем в конце добавить значение. Это очень неудобно. Вот бы в Голнге была возможность иметь вот такой вот

640:27

Speaker C

массивчик удобный, в который мы можем сразу положить несколько элементов и потом с помощью циклов удобно с ними работать, но при этом, чтобы была возможность в конец элемент какой-нибудь докинуть или удалить. Ну вот, чтобы вот всё вот настолько же было по красоте,

640:42

Speaker C

только чтобы мы могли очень удобненько докидывать элементы в конец или удалять. А такая возможность есть. И зовётся эта возможность слайсы. Значит, что же такое слайсы у нас? Ну, давайте вспомним, что массив - это просто последовательность элементов в памяти. И мы в самом начале, когда

641:05

Speaker C

массив создаём, мы указываем его размер. И этот размер статичен, то есть мы не можем его на лету поменять. То есть мы не можем просто взять и увеличить наш массив. Мы для того, чтобы увеличить наш массив, мы для этого должны создать

641:22

Speaker C

новый массив, который будет на один элемент побольше. Перекопировать все старые элементы в наш новый массив. И в конце у нас появится возможность записать новый элемент с каким-то новым значением. Ну а старый массив мы можем удалить, то есть просто

641:44

Speaker C

ничего с ним не делать. Ин сам со временем, когда поймёт, что этот массив не используется, он просто удалит его.

641:52

Speaker C

Но это всё равно очень неудобно, потому что нам нужно руками создавать новый массив, перекопировать все элементы наши старые в новый массив и в конце записывать новый элемент. Вот бы как-то это автоматизировать, чтобы нам не думать про этот весь процесс. Так вот,

642:07

Speaker C

для этого и существуют слайсы. Слайс - это структура, такая же структура, как мы с вами создаём, только написанная самими разработчиками языка. И эта структура сама под капотом, когда мы добавляем в неё новый элемент, перевыделяет память, перекопирует старые элементы, добавляет

642:29

Speaker C

новый элемент. Но для нас всё выглядит так, будто бы мы просто в массивчик одной кнопочкой можем добавить новый элемент. Сейчас расскажу немножко про внутреннее устройство слайсов, а потом посмотрим, как они работают в коде. Под капотом, ну, то есть внутри слайс

642:44

Speaker C

выглядит следующим образом. То есть это самая обычная структура, у которой есть три основных поля. Первое поле - это LН.

642:52

Speaker C

Тут хранится информация о том, какой длины наш слайс, то есть сколько в нём по факту лежит элементов. Лежит в нашем слайсе три пользователя, но лен будет равен трём. Cacity мы разберём чуть позже. И какое-то есть ещё третье поле,

643:08

Speaker C

какой-то указатель. Что это за указатель и что вообще за капасити? Ну, давайте смотреть. Вот этот вот указатель в слайсе - это указатель на массив в памяти. То есть слайс - это надстройка над массивом. Len - это сколько в этом

643:25

Speaker C

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

643:45

Speaker C

поговорить о том, как слайсы работают. Изначально, когда вы создаёте слайс, например, длины три, он и выделяет под капотом массив длиною три. Потом, если вы хотите в этот слайс добавить элементов, то для нас выглядит всё просто. Мы просто одной функцией, скоро

644:01

Speaker C

мы посмотрим, какой, берём, да, и добавляем элементик в одну строчку. Но на самом деле под капотом происходит выделение нового массива, который в два раза больше, чем старый. То есть не на один элементик больше, а в два раза. После этого слайз

644:20

Speaker C

перекопирует все старые элементы в новый массив. Вот наши три старых элемента. Он перекопировал в новый массив и после этого взял. и в конец добавил наш один новый элемент. Но помимо этого добавленного нового элемента, у нас ещё осталась неиспользуемая память. То есть

644:40

Speaker C

длина нашего слайса, она четыре, потому что тут 1 2 3четыре элемента, как бы, да длина четыре, но капасити с английского вместимость капасити у нас будет шесть.

644:56

Speaker C

Почему шесть? Потому что изначально у нас, когда мы создали слайс, он был длины три, то есть было три элемента.

645:04

Speaker C

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

645:21

Speaker C

сразу выделим массив побольше, чтобы потом можно было в оставшуюся память добавлять элементики и не приходилось так часто выделять новый массив. И размер этого нового выделенного массива, он в два раза больше, чем размер изначального. Соответственно, изначально у нас был размер три, после этого стал

645:40

Speaker C

размер шесть. То есть вместимость нового нашего массива, на который указывает наш слайс, он стал в два раза больше. вместимость стала шесть. То есть по факту в нём лежит всего четыре элемента. Всего четыре элемента в нём лежит. Было три, мы добавили один, но

645:57

Speaker C

вместимость потенциальная наша стала шесть равна. Ну и, соответственно, поинтер, повторюсь, это просто указатель на вот этот вот низлежащий массив.

646:05

Speaker C

Соответственно, старый массив у нас, он уже удаляется. Всё, только новый массив. Потом мы захотели добавить ещё элементов. Ну, хорошо, добавили. Раз, у нас стала длина пять. Ну, вместимость всё также шесть. После этого мы берём и добавляем ещё один элемент. Хорошо.

646:23

Speaker C

Теперь у нас длина стала тоже шесть. У нас длинашесть и вместимость шесть. То есть мы заполнили весь выделенный массив новыми элементами. И после этого, если мы снова захотим добавить новый элемент в наш слайс, то нашему слайсу придётся опять выделять новый

646:43

Speaker C

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

647:00

Speaker C

всё. И у нас теперь длина станет семь, а вместимость станет 12. Потому что до этого вместимость у нас была шесть, новая вместимость будет в два раза больше, 12. Ну и опять старый неиспользуемый низлежащий массив у нас удаляется, и мы начинаем указывать на

647:18

Speaker C

новый. Всё, теперь у нас указатель указывает на вот этот вот низлежащий массив. И будет так дальше происходить.

647:25

Speaker C

Мы будем добавлять новые элементы. Они будут добавляться в этот же массив низлежащий. У нас будет расти лен, то есть длина нашего массива, до тех пор, пока она не приравняется к opпасите, когда тут тоже не будет 12. Когда тут

647:41

Speaker C

будет 12 в лен, когда будет в капаacсите 12, и мы захотим опять добавить новый элемент, у нас опять будет перевыделение низлежащего массива, перегон всех старых элементов в новый массив и добавление новых элементов в появившуюся новую память. Это то, как слайс работает под

648:00

Speaker C

капотом. И в некоторых задачках, особенно когда будем с вами готовиться к собеседованиям, эта информация может быть полезна. Но пока это было чисто для общего развития. Просто представлять, как вообще эта магия происходит под капотом, как этот слайс всё сам там

648:15

Speaker C

делает. Давайте теперь посмотрим, как это выглядит в коде. Вообще, создать слайс можно несколькими разными способами. Первый способ самый простой, когда мы создаём вот так вот слайс на месте, сразу напихиваем туда какие-то элементы. Это просто убрать вот эту вот

648:32

Speaker C

циферку отсюда. Тем самым мы превратим вот эту структуру из статического массива с чётко заданным размером в слайс. Теперь это слайс.

648:44

Speaker C

Теперь у нас в User Array лежит слайс юзеров. Ну давайте сейчас просто сохраним файл и запустим нашу программу. Ну как мы видим, всё то же самое, в принципе, у нас до три человека, после три человека. Тут вотту у них рейтинг добавился, было 7,2, стало

649:00

Speaker C

8, 12. Ну хорошо, всё то же самое. В чём отличие-то? А в том, что теперь мы при помощи функции append, что с английского переводится добавить, можем в этот слайд добавить прямо на лету нового юзера.

649:13

Speaker C

Давайте посмотрим, как это выглядит. Я вот это вот пока всё закомментирую. Вот наш созданный слайс.

649:21

Speaker C

И я прямо сюда возьму. Вот так напишу user array. И как мы видим, даже редактор кода уже подсказывает, что сюда можно что-то добавить. Вот вторая строчка. Enter. User array равно append user array. И через запятую можем добавить новый элемент, который хотим

649:37

Speaker C

добавить. Ну, мы хотим добавить нового юзера. Можем прямо здесь его и создать. Таким вот образом. И передам ему имя.

649:47

Speaker C

Виталик рейтинг 4,0 премиум true. Ну, для того, чтобы более наглядно было, можно по-другому немножко расставить форматирование. Вот таким образом мы видим, что мы в слайс наших юзеров добавили нового юзера. Как работает функция append? По сути, то, что я описал с перевыделением новых

650:11

Speaker C

массивов, с перегонкой элементов старых в новый массив, это всё делает функция append. Эта функция встроена в язык программирования, поэтому она доступна из любого места нашей программы. Что она делает? Она принимает наш старый слайс. Вот он. US Ray смотрит, что у

650:31

Speaker C

этого слайса вообще под капотом происходит. Смотрит на его ленacity, массив, который он указывает, понимает, нужно ли выделять новый элемент и новый массив низлежащий не нужно. Добавляет в конец наш элемент, который мы туда передали, и возвращает новый слайс. То

650:48

Speaker C

есть почему такая странная запись, что мы usеer array передаём внутрь этой функции, но при этом сама функция, она этот же user array возвращает. То есть эта функция append, она принимает user array, производит с ним все вот эти вот

651:01

Speaker C

операции, которые мы с вами разбирали, и возвращает новый слайс. То есть, если мы здесь присвоим какой-нибудь usеer array 2, то мы увидим изменение только в этом User Array 2. Наш старый user array не изменится. Тут, на самом деле, можно

651:17

Speaker C

разбирать это более глубоко. Пока что мы на этом останавливаться не будем, потому что тема уже довольно серьёзная. Нужно этому уделять большое количество времени. Позже отдельно мы разберём более подробно, почему так происходит и что же случается с низлежащими массивами, если мы в них по сути

651:34

Speaker C

записали элемент, но вернули какой-то другой слайс. Пока что давайте условимся, что мы об этом не заботимся.

651:41

Speaker C

Для нас пока выглядит всё просто. Мы с помощью такого синтаксиса можем в наш слайс докидывать элементы сколько хотим.

651:48

Speaker C

Можем так хоть 10 раз написать, можем в наш слайз докидывать другой слайс. Это всё происходит с помощью функции append.

651:55

Speaker C

Ну, давайте выведу наш user array на экран, чтобы было видно. Вот просто вот этот вот код наш скопирую для вывода раскомментирую его и запущу программу. И как мы видим, у нас теперь четыре юзера в нашем слайсе. Вот он в конце Виталик с

652:12

Speaker C

рейтингом 4 и с премиум аккаунтом. От слайса мы можем точно также брать его длину и его вместимость. Давайте посмотрим до того, как я добавил новый элемент, и после посмотрим. Вот до вот наша lенen. Её можно взять с помощью встроенной функции

652:32

Speaker C

lенen. И вот наша капаity. Её можно взять с помощью встроенной функции capacity. Сохраняем. Это до, потом добавление нового элемента и после.

652:42

Speaker C

Сохраняю, запускаю. И вот, как мы видим, у нас до было lен 3 и capacity 3. То есть изначально, когда мы создали слайс, он просто выделил под собой массив размером три. Ну и капаси там было три, в нём три элемента, всё как бы впритык,

653:00

Speaker C

всё плотничком набито. После этого мы взяли и добавили новый элемент. И что у нас стало? Нчетыре. То есть количество элементов фактически их стало четыре, потому что мы добавили только один элемент, но капасити стало шесть. Это то, о чём я говорил, что слайс конкретно

653:17

Speaker C

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

653:35

Speaker C

выделю, и если что будет куда класть новые элементы. Но вот эта новая память, она в два раза больше старой. Ну и потом просто выводим весь наш слайс. Как ещё можно создать слайс? Давайте я удалю весь старый код. Теперь мы, в принципе,

653:48

Speaker C

поняли, для чего нам нужны массивы, для чего нам нужны слайсы. Давайте будем рассматривать на более простых примерах, чисто чтобы понять, как это с технической точки зрения устроено.

653:58

Speaker C

Создавать слайс можно ещё при помощи функции make. Как это выглядит? Ну, пускай у нас будет слайс целых чисел.

654:06

Speaker C

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

654:29

Speaker C

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

654:48

Speaker C

два, потом потом восемь, ну и так далее. Но изначально ноль. Давайте попробуем вывести этот слайдст на экран.

654:58

Speaker C

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

655:10

Speaker C

это всё работает под капотом, просто берём, да, и докидываем туда новые элементы на литу. Inslicй равно append.

655:17

Speaker C

Ну и как мы помним, первый аргумент, функция append - это слайс, а второй аргумент - это то, что мы туда хотим докинуть. Ну давайте докинем туда 10.

655:27

Speaker C

Потом докинем туда 15. Потом докинем туда 25. Ну и 150. Сохраняю, запускаю. И вот мы выводим наш слайс. И в нём лежат все элементы, которые мы в него туда динамически закинули. То есть мы одной строчкой избавляем себя от необходимости

655:47

Speaker C

вручную создавать новый массив, перегонять туда старые элементы, записывать в конец новый. Вот это всё происходит одной строчкой. Также функция append поддерживает добавление нескольких элементов за один вызов. То есть мы могли не писать вот столько-то вызовов, мы могли просто передать все

656:04

Speaker C

эти наши циферки в одной строчке. Вот это всё удаляем, запускаем. Ну и видим, что те же самые 10, 15, 25, 150. Просто в одну строчку всё это добавили. Давайте ещё посмотрим, что имеет функция make вместе со слайсом. То есть мы могли сначала задать

656:23

Speaker C

здесь не ноль, а пять. Что бы это значило? Это значило, что у нас, когда создавался слайс, то низлежащий массив, который под этим слайсом у нас лежит, он бы имел размер пять, но при этом он был бы до краёв заполнен

656:42

Speaker C

элементами типа integer со значением по умолчанию. Значение по умолчанию у интеджера ноль. То есть наш слайс был бы изначально забит пятью нулями. Ну давайте я закомментирую какое-то добавление в слайс и выведу просто то, что нам вернула бы функция make. Вот мы

656:59

Speaker C

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

657:14

Speaker C

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

657:32

Speaker C

Что тут изменилось? Теперь тут создастся новый слайс, у которого длина низлежащего массива будет пять, но при этом он будет заполнен нулём элементов.

657:42

Speaker C

Ну, а это значит, что он будет, в принципе, пустой. И это уже довольно часто используется. То есть довольно часто при создании слайса мы заранее знаем, какой размер наш слайс должен иметь. Мы можем написать вот таким вот образом, что мы хотим низлежащий массив

657:59

Speaker C

выделить размером пять, но при этом ничем его не заполнять. Заполнить его нулём элементов. Давайте выведу на экран. И, как мы видим, у нас пустой слайс. Но что будет, если я выведу лен этого слайса и его капасите? Давайте подумаем.

658:16

Speaker C

Нулен, то есть длина этого слайса, очевидно, будет ноль, потому что в нём нет элементов, значит, в нём ноль элементов, но капасити будет пять. То есть капаacity - это вместимость, это размер вот этого низлежащего массива, сколько элементов мы можем запихнуть до

658:31

Speaker C

того, как мы будем переполнены и до того, как нам придётся выделять новый массив. Ну, давайте запустим программу и увидим, что у нас lен, но capacity 5. То есть вместимость наша пть. И мы можем теперь целых пять раз в этот слайд докинуть новый элемент.

658:48

Speaker C

И мы будем избавлены от необходимости перевыделять память, перевыделять новые низлежащие массивы. В чём преимущество?

658:57

Speaker C

Да, просто-напросто в том, что когда мы перевыделяем новый массив, перекидываем старые элементы из старого массива в новый массив, это всё требует времени процессорного. Поэтому просто долго это всё происходит. Мы излишне тратим ресурсы нашего компьютера на то, чтобы найти новую свободную память подходящего

659:16

Speaker C

размера, расположить там наш базовый массив, перекинуть все старые элементы. Это всё довольно долго, на самом деле.

659:23

Speaker C

Поэтому хорошая практика вот таким вот образом заранее предвыделять этот базовый массив, чтобы в него можно было накидывать элементов, не боясь, что там будет какое-то перевыделение. Но это я уже прямо в какие-то дебри оптимизации иду. На самом деле, на первых порах

659:37

Speaker C

новичку можно вообще про это не думать, забить на это болт, просто писать make int запяль. Ему создастся пустой слайз, в котором не будет элементов и в котором будет низлежащий массив изначально размером ноль. Ну и потом опендеми он туда накидает вообще, что хочет, и

659:55

Speaker C

пофигу, что там под капотом что-то перевыделится, сколько-то там он наносекунд потратит на это. Ну и ладно.

660:01

Speaker C

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

660:18

Speaker C

пользователей, у нас в одной части программы могут прийти пользователи, в другой части программы могут прийти пользователи, и мы их просто вот так вот через append можем накидать в наш слайс и потом, ну, к примеру, сохранить в базу данных. Это очень удобно. Слайсы вообще

660:33

Speaker C

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

660:47

Speaker C

вместе с функцией append встроены, делают это всё за нас. И нам всё, что остаётся - это создать слайс и кидать в него элементы, если мы захотим. Дальше у нас идут мапы. Что вообще такое мапы?

660:59

Speaker C

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

661:19

Speaker C

обращаться к ним с помощью индексации. Там вот это у нас нулевой элемент, это первый элемент, это второй, это третий, это четвёртый. Вроде всё круто, всё удобно, но бывают случаи, когда мы хотим иметь доступы к элементам не по индексу

661:32

Speaker C

индекс0, индекс 1, индекс 2, а когда мы хотим иметь доступ к этим элементам по какому-то ключу, представим, что мы с вами разрабатываем сервис погоды и хотим иметь информацию в следующем виде. У нас есть какое-то число. Ну, число имеется в

661:48

Speaker C

виду число месяца, как вот в календарике. Вот есть у нас календарик. И у нас тут одиннадцатое число, двенадцатое число, тринадцатое, четырнадцатое, пятнадцатое, ну и так далее. Одиннадцатое число, двенадцатое число, тринадцатое число, там четырнадцатое, ну и вот пятнадцатое. И

662:08

Speaker C

мы хотим, просто передав в нашу какую-нибудь там структуру данных или что-нибудь такое, просто передав число, сразу же получить погоду, которую мы прогнозируем на это число. Ну вот, например, одиннадцатого у нас по прогнозу должно быть там +3, двенадцатого по прогнозу должно быть +6,

662:29

Speaker C

потом +9, потом хопа, мороз, короче, четырнадцатого дал -4°. Ну и потом пятнадцатого у нас 1грас тепла. То есть мы хотим каким-то образом иметь данные вот в таком вот виде, то что мы передаём туда какое-то число и получаем на это число какой-то прогноз.

662:49

Speaker C

Давайте подумаем, как бы мы вообще эти данные могли хранить. Ну могли бы хранить как-то отдельной переменной. Ну вот представим, как бы мы это хранили отдельной переменной. Ну то есть вот у нас было бы погода с английского везеer.

663:02

Speaker C

Везер одиннадцатая, да? Это у нас 3°. Ну, можно +3 написать, но, в принципе, это значение не имеет. С точки зрения языка программирования это будет воспринято как обычная тройка.

663:13

Speaker C

Везер двенадцатая у нас +ше везер тринадцатое +9 везер четырнадцатое -че и везер пятнадцатое +1. Ну, вроде как какой-то прогноз погоды. А теперь мы хотим его весь вывести, да, весь там вывести на экран пользователю. Ну, нам нужно, как обычно, выводить каждую переменную

663:39

Speaker C

отдельно. Везер 11, Везер 12, 13. О'кей. Теперь представим, что мы вот это всё показали пользователю. Всё хорошо. Теперь нам пришёл новый прогноз погоды уже на следующие числа. И нам нужно опять, короче, лезть в код, опять как-то создавать новые переменны. В

664:00

Speaker C

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

664:12

Speaker C

есть 30 переменных - это ещё пять раз сверху. 1 2 3 4 5. Ну, и была бы у нас вот такая вот красота. Хорошо. Вот он наш прогноз погоды на месяц. И как нам вообще с этим работать? Допустим, нам

664:25

Speaker C

пришёл прогноз на новый месяц. И что нам как-то нужно лезть в код, перемещать эти переменные, их переприсваивать? Ну, сразу начинаем путаться. Как-то неудобно. Всё непонятно. О'кей. Через отдельные переменные как-то не круто.

664:40

Speaker C

Могли бы это хранить всё в массиве. На самом деле у нас был какой-то массив везеer, и мы бы хранили в нём нашу погоду. Небольшая ремарочка. Тут, конечно же, мы с вами создаём именно слайс. Это не массив, это слайс. Но я

664:55

Speaker C

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

665:14

Speaker C

если когда-нибудь кто-нибудь назовёт слайс массивом, но подразумеваться будет именно динамический массив, то есть слайс. Ну, допустим, нулевой элемент - это вот одиннадцатое число. То есть у нас +3, потом у нас +6, потом у нас +9, потом у нас -4. Потом у нас плюс один.

665:33

Speaker C

Хорошо. А потом к нам пришёл пользователь и сказал: "Дайте мне погоду на четырнадцатое число". И мы такие: "Э, а что из этого, собственно, четырнадцатое?" Ну хорошо, мы бы могли помнить, что это одиннадцатое, это двенадцатое, это тринадцатое, это четырнадцатое. То есть наш массив погоды

665:51

Speaker C

с индексом 01 2 3 - это четырнадцатое. Но это капец как неудобно. То есть мы должны помнить, что везер с индексом 3 - это четырнадцатое число. Максимально не интуитивно, максимально непонятно. Ну давайте выведем. Увидим, да, что вот у

666:09

Speaker C

нас четырнадцато - это -че. То есть, ну, в принципе, можно, да, в принципе можно.

666:14

Speaker C

Нас, ну, никто не ограничивает, но это очень неудобно. Везер с индексом 3 - это четырнадцатое число. А что-то какая-то фигня. Ну, хотелось бы, если честно, писать везер. И тут 14, да? И это бы значило четырнадцатое число. Ну тогда

666:28

Speaker C

было бы вообще удобно. Ну, погода с ключиком 14, значит четырнадцатое число. Погода с ключиком пять, значит пятое число. Ну, гораздо удобнее, на самом деле. И GOLNG предоставляет такую возможность хранить данные вот в таком вот формате. Как этот формат выглядит?

666:45

Speaker C

Это уже не просто последовательное хранение какое-то в памяти, потому что если у нас в памяти что-то последовательно хранится, то обращаться мы к этому можем просто по индексу и всё. А мы можем уже не задумываться о том, как это именно лежит в памяти, а

667:00

Speaker C

можем хранить это в формате ключ значения. То есть ключом у нас может быть практически любой тип, который мы захотим, пока не вдаёмся в подробности, но всё, что мы изучили, может быть ключом. Число, строка, какая-нибудь наша своя структура. А значение может быть, в

667:15

Speaker C

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

667:31

Speaker C

называется как раз-таки мапа. То есть мапа - это с английского map, то есть отобразить. У нас есть какое-то отображение. В нашем случае отображение числа в месяце на погоду этого самого числа. То есть у нас одиннадцатого числа будет +3, двенадцатого числа + 6.

667:47

Speaker C

Получается, у нас ключ - это число в месяце, а значение - это погода. Такой формат данных называется Kvalelue. То есть с английского - это ключ значения.

667:57

Speaker C

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

668:11

Speaker C

ключикам нам будут возвращаться значения. Давайте посмотрим, как это выглядит в языке программирования. Я уже буду использовать не слайс, я буду использовать как раз-таки наши мапы. Как создать мапу? Ну, один из способов - это написать ключевое слово map, потом в

668:27

Speaker C

квадратных скобочках передать тип ключа, который мы хотим видеть. А у нас тип ключа - это целое число. Ну, потому что числа месяца можно хорошо представлять целым числом. Не дробью там, не бульном, да, никаким, а именно целым числом.

668:40

Speaker C

Соответственно, ключ у нас целое число. Ну и значение тоже будет целое число, потому что у нас градусы Цельсия.

668:47

Speaker C

Значение тоже целое число. Потом нужно поставить фигурные скобочки. и в открывшихся фигурных скобочках написать наши желаемые пары ключ значения. Мы берём, да, и пишем 11 двоеточе + 3. Это значит, что у нас появился ключ 11 и значение +3. Потом

669:07

Speaker C

есть ключ 12 и значение + 6. 13 + 9, 14 - 4 и 15 + 1. Мы создали с вами мапу с ключами 11, 12, 13, 14, 15 и соответствующими им значениями. То есть мы вот этой вот записью взяли, да, и

669:29

Speaker C

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

669:44

Speaker C

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

670:02

Speaker C

двенадцатого числа плюс 6? Вот двенадцатое число плюс 6, а пятнадцатого А пятнадцатого один, а одиннадцатого 3°. Как мы видим, это наиболее удобный формат хранения данных, который подразумевают, что у нас есть какой-то ключ, в данном случае число месяца, и на него должно быть отражено,

670:27

Speaker C

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

670:46

Speaker C

когда лучше просто обычную переменную. Это всё приходит с опытом, поэтому повторяю: работа, работа, практика, ещё раз практика. Хорошо, что будет, если мы попробуем получить ключ, который мы не задавали? Ну, давайте выведем погоду тридцатого числа, хотя мы её как

671:05

Speaker C

бы ещё не прогнозировали. Запускаем и видим, нам вывелось ноль. Что это значит? Это значит, что когда мы в мапе пытаемся получить ключ, который мы не задавали, то значение возвращается по умолчанию. То есть значение по умолчанию для интеджера - это ноль, поэтому

671:22

Speaker C

вернулось ноль. Если бы у нас значением была строка, то вернулась бы пустая строка. Если бы значением был флот, то вернулось бы 0,0. Ну и так далее. То есть, если мы пытаемся взять какой-то ключ, которого у нас не существует, который мы ещё не

671:36

Speaker C

задавали, то возвращается значение по умолчанию. Но как отличить, когда нам вернулось значение по умолчанию, а когда у нас действительно 0°, да? То есть, допустим, у нас реально бы мы задали ключ 30, то есть тридцатое число, и там было бы 0°, и мы бы получили тот же

671:53

Speaker C

самый вывод, как отличить в голенге, помимо того, что мы можем получать из мапы по ключу какое-то значение, мы можем ещё узнавать, является ли это значение значением по умолчанию. Как это делается? Допустим, в переменную C, то есть Цельсий, я буду класть нашу погоду

672:11

Speaker C

тридцатого числа. Ну и выведу на экран. Собственно, тот же самый ноль, ничего не изменилось. Мы просто в переменную C записали погоду тридцатого числа и вывели на экран. Ну, у нас есть этот ключик 30 и он нулю равен. А если этого

672:26

Speaker C

ключа нет, то есть мы никакого прогноза на тридцатое число не давали, но у нас опять ноль. Как отличить в гонге? Для этого мы можем после получаемого из мапы значения написать запятую и получать вторую переменную ок. Это переменная типа бул. Она говорит о том, является ли

672:47

Speaker C

полученное значение значением по умолчанию или это всё-таки валидное значение, которое было задано на получаемый ключ. Давайте выведем это ок на экран. Запускаем и видим, что оно false.

673:02

Speaker C

Что это значит? Это значит, что не ок. Это значит, что нехорошо. То есть у нас не было задано этого ключа, поэтому значение C - это значение по умолчанию.

673:13

Speaker C

А если мы тут зададим наш ключик и попытаемся ещё раз, то увидим, что true.

673:18

Speaker C

То есть о'кей, да? О'кей. C - это не значение по умолчанию. Это реально там лежит такое значение. У нас реально есть такой ключик. Ну и тут, чтобы у нас не было, там 13 тоже увидим, что trueue, что наш ок true. То есть, да, всё чётко.

673:33

Speaker C

А если этого ключа не будет, то мы увидим, что тут флs? Ну и повторюсь, в принципе, как всегда, тут уже наша задача, как разработчиков понять, нужно ли нам проверять, что это значение по умолчанию, или нам достаточно просто получить любое значение, даже если там

673:47

Speaker C

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

674:02

Speaker C

Иначе выведу на экран BД. Запускаем. Ну и смотрим, что у нас выявилось. BТ. Почему? Потому что мы попытались получить значение по ключу 30, но этого значения у нас не было. Ну а если я попытаюсь получить значение по существующему ключу, вот 11 у нас есть,

674:21

Speaker C

я вижу. Окей. Ну потому что о у нас вернулось true. Хорошо. Теперь вопрос: как мы можем в нашу мапу добавить какой-то элемент? Да, всё просто. Мы пишем нашу мапу, передаём туда любой ключ, который захотим, ну, например, 20, и пишем через равно значение, которое мы

674:40

Speaker C

хотим положить по ключу 20. Ну, пускай у нас двадцатого числа будет прогноз -10. Всё. И теперь у нас двадцатого числа будет -10. Всё. Просто берём вот так вот и записываем. Если мы таким образом будем создавать ключ, который уже имеется, то имеющееся значение будет

674:59

Speaker C

перезаписано. То есть, ну вот, например, мы захотим создать ключ на одиннадцатое число, а он у нас уже есть. Что будет?

675:07

Speaker C

Ну, оно у нас просто перезапишется. Давайте выведем нашу погоду одиннадцатого числа до перезаписи и после. Запускаем. Ну и видим, что везер одиннадцатого числа до перезаписи был три.

675:23

Speaker C

+3°. Перезаписали, он стал -10 у нас. Хорошо. Теперь предположим, что нам пришли корректировки по прогнозу погоды, и мы узнали, что погода каждого числа должна стать на 1° теплее. Ну, там какой-нибудь тёплый циклон мы увидели, учли его в нашем уравнении и поняли, что

675:42

Speaker C

у нас погода каждый день должна стать на 1° теплее. Ну, что мы могли бы для этого сделать? Ну, первое, самое очевидное, просто получить каждый наш ключик и прибавить к нему единичку. Vezer 11, Vezer 12, Vezer 13, Vezer 14 и вер. Вот мы прошли по

676:02

Speaker C

каждому нашему ключику и прибавили ему один. Ну а если у нас прогноз на 30 дней, нам придётся вот 30 раз вот так вот делать. Как-то не круто. Хотелось бы как с массивами или как со слайсами просто циклом пройтись по каждому

676:16

Speaker C

элементу и прибавить единичку. А мы можем так сделать. Как выглядят циклы по мапе? Циклы по мапе всегда используются в новом формате, то есть не через создание какой-то там переменной i, потому что i - это индекс. Мы как бы

676:30

Speaker C

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

676:43

Speaker C

помощью нового формата наших циклов. Как это выглядит? For k value = range weather. Что тут происходит? Я пробегаюсь циклом. По каждой паре ключ значения в нашей мапе. И на каждой итерации этого цикла мне в переменную K будет класться ключ, а в переменную

677:03

Speaker C

value будет класться значение. Ну, как мы видим, у нас K value. Всё логично. Давайте выведем на экран. Вот это вот я пока закомментирую и просто выведу на экран. Запятая value. Запускаю и видим, вывелась наша мапа, но в каком-то не том

677:21

Speaker C

порядке. То есть, да, у нас почему-то 15 из конца перешло в начало. Это связано с внутренним устройством мапы в том, что нам не гарантируется порядок элементов в ней. Это значит, что на порядок элементов мы не должны завязываться. Это

677:36

Speaker C

не массив. Нам самое главное, что нам гарантируется сохранение вот этой вот привязки ключа к значению. И нам неважно, в каком порядке это всё расположено. Вот, если честно, реально неважно. Нам главное, что сохраняется привязка значения ключу. И мы в любой

677:56

Speaker C

момент, как бы у нас эти элементы там в памяти не располагались, мы всегда можем получить доступ к пятнадцатому числу и узнать, что там плюс один. мы всегда можем получить доступ к одиннадцатому числу и узнать, что там плю3, и нас

678:09

Speaker C

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

678:26

Speaker C

получаем. Хотя и все пары ключзначения остались верными. пятнадцатого числа у нас плюс одина + 3, двенадцатого птринатого плю9, ну и 14 - 4. То есть пары ключ значения у нас все сохранились, просто их порядок перемешался. Но для мапы, для Kvue

678:47

Speaker C

хранилища это неважно. Важно, что осталось валидное, правильное соответствие значения какому-то ключу. Вот таким образом мы можем пробегаться циклом по нашей мапе. И что мы можем с ней делать? Да всё просто. Мы можем брать нашу мапу, брать ключ и делать

679:02

Speaker C

плюс равно 1. Всё, видим, тут value не используется. То есть, по сути, вы бы могли сказать: "Так, почему ты, когда пробегаешься по мапе, ты не делаешь value п = 1? То есть мы пробегаемся по каждом вот этому вот value и делаем плюс

679:16

Speaker C

равно о. Ну давайте посмотрим, что вообще будет. Выведем мапу на экран просто одной строчкой. Убираю неиспользуемую переменную.

679:27

Speaker C

Запускаю. Вот наша мапа. Как мы видим, одиннадцатого числа как было плю3, так и осталось. Двенадцатого числа как было плюше, так и осталось. Ну, ничего не изменилось. Типа пятнадцатого как было плюс оди, так и осталось. Хотя мы вроде каждому вот этому value прибавили один.

679:41

Speaker C

Ну, тут ситуация такая же, как была со слайсами. Тут в цикле у нас не сам вот этот вот элемент, а просто его копия, сохранённая в переменную value. Поэтому тут мы меняем эту самую копию, не меняя изначальный элемент. Для того, чтобы

680:00

Speaker C

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

680:20

Speaker C

элементу прибавляем один. Ну и тут у нас теперь value не используется нигде, поэтому мы его ставим нижним подчёркиванием. Запускаем программу и видим, что теперь у нас изменились наши значения. Теперь одиннадцатого числа не +3, а +4. Четырнадцатого числа не -4.

680:39

Speaker C

А, мину3. То есть вся наша погода на каждый день потеплела на 1°. Таким образом, мы можем мапы создавать и можем с мапами работать при помощи циклов. То есть можем по мапам пробегаться, можем делать с ними какие-то операции, можем

680:55

Speaker C

делать операции с какими-то их значениями, можем просто выводить на экран циклом, если хотим. Ну и так далее. По сути, просто зависит от поставленной перед нами задачи. Как ещё мы можем создавать мапы? Ну, вообще, при создании мы можем просто указать пустые

681:10

Speaker C

скобочки. Тогда создастся пустая мапа без каких-либо элементов. И точно также можем в неё по чуть-чуть добавлять какие-то элементы. Ну, допустим, у нас вот будет седьмого числа у нас погода + 20°, а восьмого числа у нас будет погода +25. Потом у нас прибавка по 1° и вывод

681:32

Speaker C

на экран. Соответственно, седьмого числа у нас будет +21, восьмого числа +26. Также мы можем создавать мапу через функцию make, так же, как мы создавали слайс, то есть make тут передаём, что это мапа, ключом является integer, значением тоже integer. И всё, мы можем

681:50

Speaker C

не передавать дополнительно размер, а можем и передать. Что будет, если мы передадим сюда размер 10? Ну, по сути, наша мапа никак не изменится. Вот видим то же самое. Но мы заранее для неё, точно так же, как для слайса,

682:04

Speaker C

предвыделим память. И когда мы будем в нашу мапу добавлять какие-то элементы, у нас не будет происходить перевыделение новой памяти, поиск свободного места.

682:15

Speaker C

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

682:27

Speaker C

Поэтому просто на словах мы понимаем, что есть функция make. Мы можем с помощью неё просто создать мапу, а можем сразу же этой мапе предвыделить какое-то количество элементов, чтобы, когда мы добавляли туда новые ключи, новые значения, у нас это всё происходило

682:43

Speaker C

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

683:00

Speaker C

допустим, строку на булин. Ну, к примеру, перед нами стоит задача, нам нужно хранить данные о людях. Нужно по имени человека сразу понимать, был ли он судим.

683:23

Speaker C

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

683:36

Speaker C

проблемой, что и с хранением нескольких юзеров. А если у нас будет миллион человек в нашей структуре, ну и что нам миллион переменных создавать? Ну что-то не круто. А если в массиве? Ну давайте массив у нас там. А массив чего? Ну,

683:52

Speaker C

может быть, массив булианов, типа truee - это значит судим. Флс - это значит не судим. Ну, хорошо. True, false. True, fфse, true. О'кей. А где имена людей?

684:05

Speaker C

Как нам сюда имя какое-то передать и узнать, был ли он судим или нет? Ну, что-то вообще как-то не прикольно.

684:12

Speaker C

Непонятно, неудобно. Тут отличным решением будут мапы. У нас ключом будет имя человека. Вася, например, а значением будет информация о том, судим он или нет. То есть true - это судим. А, например, Петя, FSE, это значит, что не судим. Ну

684:33

Speaker C

и так дальше. То есть тут у нас могут быть, в принципе, любые имена, а тут любые значения. True или fфse. Хорошо, давайте сделаем такую мапу. Назову её просто криминал. Это будет мапа. Ключом будет являться строка, потому что имя

684:47

Speaker C

нам лучше всего хранить в строке. Имя в числе или имя в буле не особо не похранишь, да? Имя у нас в строке, то есть ключом будет стринг, а значением булин, то есть либо судим, либо нет. И всё. И мы можем спокойно сохранять. Ну,

685:02

Speaker C

допустим, вот у нас Вася он судим. Петя, он не судим. Антон у нас тоже не судим. Вова тоже не судим. А вот Алексей. у нас судим. Ну и, соответственно, вот наша мапа, наше Kvue хранилище, в котором мы можем передавать

685:27

Speaker C

имя человека и сразу же узнавать, был ли он судим или нет. То есть, как это выглядит. Допустим, я хочу узнать, судим ли у нас был Вова. То есть в переменную С я буду класть информацию о том, судим он или нет, а в переменную окцию о том,

685:43

Speaker C

является ли полученное значение значением по умолчанию или нет. Потому что, если мы попробуем узнать о судимости человека, которого нет в базе, то нам вернётся фолс, потому что значение по умолчанию для Булина это фолс. Я хочу знать, когда мне конкретно

685:57

Speaker C

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

686:12

Speaker C

То есть мы даже можем смотреть, что если у нас не ок, в таком случае человека нет в базе. Человека нет в базе. И можем сразу же завершить нашу программу, завершив нашу функцию main, просто написав return. Всё, мы завершим нашу функцию

686:31

Speaker C

main. Если мы продолжим выполнение, значит, это условие не выполнилось, значит, у нас всё-таки ок. Если ок, значит, выводим человек найден в базе. И дальше смотрим, что если C, то есть если вот эта вот переменная, которую мы получили, это значение, если он судим,

686:54

Speaker C

тогда человек судим. Иначе человек не судим. Ну давайте запустим нашу программу. человек найден в базе. То есть мы получали Антона. Антон у нас в базе есть. Информация о нём фолс, то есть не судим. И мы это видим. Человек не судим.

687:17

Speaker C

А если мы сюда передадим, к примеру, Алексея, запустим. Человек тоже найден в базе, да? У нас есть Алексей, он судим, потому что у него тру. Теперь давайте попробуем получить человека, которого у нас нету в базе.

687:34

Speaker C

Никита. Запускаем. Человека нет в базе. Мы попытались получить из нашего хранилища Никиту. Нам в C вернулось значение по умолчанию, то есть false. Но в переменную ок нам тоже вернулось fse, то есть не ок. Что значит не ок? Это

687:52

Speaker C

значит, что человека нету в нашей мапе. И вот это условие, то есть не ок, фse, но у нас инверсия. Мы узнаём, что у нас не ок. Выполняется этот блок кода, человека нет в базе и завершаем нашу программу. Таким образом, мы узнали, что

688:06

Speaker C

в мапе ключом может быть практически всё, что угодно, а значением, в принципе, что угодно. То есть строки, целые числа, структуры, булины, дробные числа. Всё. Вот всё, что мы на данный момент с вами умеем, всё это может быть и ключом, и значением. И уже наша задача

688:23

Speaker C

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

688:45

Speaker C

неё мы положили последовательно элементики наши. И всё, можем эти элементики менять, но новые добавлять не можем. Придётся создавать новый массив и ла-ла-ла. Массив можем вводить на экран.

688:57

Speaker C

У массива мы можем брать его длину и можем брать его вместимость. Ну, у статического массива его длина и вместимость всегда будут одинаковые, потому что в нём всегда будет ровно столько элементов, сколько он может в себя вместить. Дальше слайсы. Слайсы,

689:11

Speaker C

помимо прочего, мы можем создавать с помощью функции make. В данной её версии мы создадим слайсн размерностью ноль, но вместимостью пять. То есть заранее предвыделим базовый массив на пять элементов. Потом с помощью функции опенда напихали туда 4 5 6 и вывели на

689:29

Speaker C

экран. У слайса мы также можем брать его лен, то есть длину. Длина слайса - это фактическое количество в нём элементов.

689:37

Speaker C

В данном случае в нём всего три элемента. И можем брать у слайса Cacity, то есть это вместимость нашего слайса. В данном случае это пять. То есть мы ещё помимо этих трёх опендов можем два раза запендить без перевыделения новой

689:52

Speaker C

памяти. А если мы шестой раз запендим, то придётся выделять новый базовый массив. и узнали, что такое мапы, что это K value хранилище. Хранилище типа ключ значения, где ключом может быть всё, что мы с вами на данный момент прошли, и значением тоже любой тип,

690:08

Speaker C

любая наша кастомная структура. Создавать маap мы можем с помощью функции make добавлять ключи и элементы в неё просто следующим образом. Ну и у мапы мы можем брать только lенen, то есть количество в ней элементов.

690:21

Speaker C

Capacity у мапы мы взять не можем, но зато можем предвыделить для неё какую-то память. По сути, это и есть капасити мапы, но по каким-то причинам разработчики языка программирования Goeng запретили нам пытаться получить вот это самое число, обозначающее вместимость нашей мапы. То есть, если я

690:40

Speaker C

напишу кап мапа, у меня будет подчёркивание, что я не могу использовать мапу в функции capacity.

690:47

Speaker C

Ну, как говорится, и ладно. Давайте запустим нашу программку. Ну и видим вот наш массив 1 2 3, длина 3, капаity 3, слайс 4 5 6 длина 3, потому что три элемента всего, но капасити пять, то есть базовый массив под этим слайсом, он

691:03

Speaker C

побольше ещё на два элемента. Ну и мапа наша, которая как обычно выводится в каком-то непонятном порядке. Сначала март, потом февраль, потом вообще январь. Вон всё перевернулось. Ну и можем узнать, сколько элементов у нас в мапе хранится. Это три. Можем с помощью

691:17

Speaker C

этих структур данных очень удобно работать над большим количеством информации, обрабатывая эту информацию в циклах и с помощью небольшого кода пробегаться по каждому элементу в наших [музыка] хранилищах. И последняя тема, которую мы разберём в первой части нашей серии уроков - это пользовательский ввод.

691:38

Speaker C

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

691:53

Speaker C

Пользовательский вод - это когда пользователь нам что-то в программу сможет написать, а мы это сможем прочитать и сделать на основе этого какие-то действия. То есть до этого у нас были программы, которые просто описывают какой-то алгоритм, они запускаются, но всё, что мы с этими

692:06

Speaker C

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

692:21

Speaker C

им команды. Ну давайте посмотрим на наше простенькое задание. Сразу скажу, в этом нет какого-то великого смысла, потому что конкретно работать с пользовательским вводом и обозревать вместе в одном проекте, собирать все пройденные в этом уроке темы, в этой серии уроков, в этой части, мы с вами

692:38

Speaker C

будем на нашем тренировочном проекте. Ссылку на исходные коды тренировочного проекта вы найдёте в описании, а видео с тем, как мы будем писать этот тренировочный проект, с объяснениями вы найдёте в приватном сообществе. Так вот, смотрим на задачу. У нас нужно, чтобы,

692:54

Speaker C

если кто-то ввёл команду "Дбавить" и после этой команды что-то написал, то мы вывели на экран. Вы хотите добавить и вот то, что написал пользователь. То есть, допустим, у нас программа запущена и пользователь пишет "Добавить приправы". Опа. И мы прочитаем вот этот

693:11

Speaker C

вот пользовательский ввод. И мы поймём по первому слову, что пользователь хочет именно что-то добавить. И потом поймём, что именно он хочет добавить, и выведем это на экран вот таким вот образом. вы хотите добавить. И вот то, что пользователь тут написал, даже если тут

693:25

Speaker C

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

693:44

Speaker C

удалить приправы лук-морковь. И выглядят они вроде очень похожи, но если пользователь пишет добавить, мы должны понять, что это именно добавление. А если пользователь первым словом пишет удалить, мы должны понять, что это именно удаление. Вот. Ну и можно будет

693:58

Speaker C

написать в нашу программу help. Тогда выведется список доступных команд. Ну, у нас всего две команды. И если какая-то неизвестная команда будет, то тоже мы выведем список доступных команд. Давайте посмотрим, как это можно сделать в Голенге. Довольно удобно. В Гошке есть

694:13

Speaker C

ящик с инструментами BOF IO. Ну, пакет BuФО. И в нём есть возможность создать сканер. Сканер - это нечто, что будет читать наш ввод, читать поток информации. Но как понять, что именно за поток информации сканер будет читать?

694:28

Speaker C

Ему для этого в конструктор нужно передать os. STDIN. stdin - это стандартное название для самого обычного пользовательского ввода в консоли. То есть это какой-то входной поток данных.

694:42

Speaker C

В данном случае это именно поток данных из консоли, потому что стандартный поток. Ну, типа стандартный входной поток. Таким образом, мы с вами создадим сканер, который будет читать команда из консоли. Давайте сканер, который нам возвращается из конструктора, будем класть в переменную. Всё, мы создали с

694:58

Speaker C

вами сканер. Таким образом, мы можем начать читать наши первые команды. До чтения команды я выведу на экран введите команду и потом сразу же буду эту самую команду читать. У сканера есть метод скан. Что он делает? Он блокирует выполнение программы на момент вызова

695:18

Speaker C

вот этого метода и ждёт, пока пользователь что-то введёт. Пользователь может вводить, вводить, вводить, вводить. Скан всё это время будет ждать.

695:25

Speaker C

Как только пользователь нажмёт Enter, тогда скан сразу же разблокируется и вернёт нам булевское значение ОК. То есть, что это за булевское значение? Оно будет говорить, был ли пользовательский ввод прочитан успешно или нет. То есть вот этот вот наш скан возвращает

695:40

Speaker C

какой-то ОК. И мы после этого должны проверить, что если не ОК, то есть если какие-то ошибки пользовательского ввода, я так и напишу ошибка ввода. Ну и завершу нашу программу тем, что просто завершу функцию main через return.

695:53

Speaker C

О'кей. В Гошке есть ещё такие конструкции, которые позволяют вот такую запись, когда мы что-то в строчке получаем какое-то значение и сразу же в следующей строчке хотим проверить это значение в каком-то условном витвлении, есть для этого следующие конструкции.

696:09

Speaker C

То есть мы прямо в ифе можем вызывать сканер и тут же проверять, если он не ок. Что это значит? Я вот достигнул вот этого ифа. Тут я сразу же начал читать из сканера. Жду, пока пользователь что-то введёт. Как только пользователь

696:25

Speaker C

что-то ввёл, скан вернул значение булевское ок или не окложил вот в эту переменную. Потом сразу же после этого идёт проверка условия, что если не ок, ну, если не ОК, тогда у нас ошибка ввода и завершение функции. То есть это такая

696:41

Speaker C

странная конструкция, которая на самом деле является просто укорочением от того, что мы написали в первый раз. То есть вот это и вот это - это одно и то же. Просто в гошке есть такая вот непривычная, на первый взгляд

696:53

Speaker C

конструкция, которая позволяет получать какое-то значение в одной строчке и сразу же в этой строчке проверять его в условном витвлении. используется, на самом деле довольно часто и сильно удобно. Так вот, мы с вами узнали, что пользователь что-то ввёл, и мы узнали,

697:06

Speaker C

что он это вёл успешно. Как нам прочитать то, что он ввёл? То, что ввёл пользователь, можно получить при помощи метода текст из того же самого сканера.

697:15

Speaker C

После того, как мы прочитали всё, нам текст вернёт строку, которую вёл пользователь. Давайте выведем её на экран. Запускаю программу. Введите команду. И видите, введите команду и всё. И наша программа заблокиролась. Она ждёт, пока мы что-нибудь введём. Ну давайте я введу.

697:34

Speaker C

Привет. Как дела? Enter. Оп, всё. И текст мы вывели. Привет. Как дела? То есть мы прочитали благодаря вот этому сканеру наш пользовательский ввод и сохранили его в переменную текст. О'кей.

697:47

Speaker C

Но, как мы видим, у нас тут просто какая-то большая строка. И то есть, если я введу, например, добавить чеснок, я как бы понял, да, что типа команда у меня добавить чеснок. Но как мне вот получить вот это первое слово и проверить, что

698:03

Speaker C

оно именно у меня добавить, чтобы я понял, что пользователь хочет что-то добавить, или, может быть, там будет слово удалить. Вот как мне это понять?

698:10

Speaker C

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

698:25

Speaker C

вот эту команду, которая у нас может быть разбита там на разные пробелы, например, добавить лук, чеснок, морковь, свеклу, да, и нам нужно вот это вот всё каким-то образом прочитать и понять, что именно первое слово у нас - это добавить. Так вот, в Гошке есть

698:42

Speaker C

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

699:01

Speaker C

строка будет отдельным словом. И я таким образом смогу получить этот массив строк, получить его первый элемент и узнать, что это за команда. Выглядит это следующим образом. Есть у нас ящик с инструментами strings стандартный. Вот он для работы со строками. И в нём есть функция

699:16

Speaker C

fields. Ну или в нём есть инструмент fields. Что он делает? Он как раз-таки выполняет то, что мне нужно. Принимает на вход строку и возвращает нам массив.

699:25

Speaker C

Ну или слайс, если говорить более точным языком, строк. То есть возвращает нам слайс строк. Как он сформирует этот слайс строк? Он просто по переданной в него строке пройдётся, и каждый пробел для него будет означать разделение и создание новой строки. Поэтому мы на

699:42

Speaker C

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

699:53

Speaker C

Для того, чтобы нам использовать библиотеку какую-то стороннюю, нам нужно сначала самим стать модулем. После этого мы можем получить нашу самую библиотеку go get. И передаю ссылочку на нашу библиотеку pп. Вот она у нас скачалась. Теперь я могу её

700:09

Speaker C

использовать. Pp.println. И тут я буду передавать вот эти вот наши слова и буду печатать слайс из слов, которые мы получили из пользовательского ввода. Запускаю программу и вот ввожу команду добавить лук, чеснок огурец помидор. Опа, вот наш весь текст. А вот

700:34

Speaker C

наши отдельные слова. Мы все те слова, которые ввёл пользователь, взяли и разделили на отдельную строку в слайсе строк. Что это нам даёт? Теперь я могу просто из этих вот всех слов, из этого слайса слов брать самый первый элемент,

700:51

Speaker C

да, и я буду понимать, что это команда просто fields, да, вот эти вот наши вот словечки с индексом ноль. И всё. И тогда я пойму, что самая первая команда, как она выглядит и что значит. Давайте я опять введу то же

701:07

Speaker C

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

701:22

Speaker C

просто создавать переменную cmd, как бы буду туда класть команду и там будет лежать fields ноль, то есть как раз-таки команда. А потом просто смотреть, что если cmd равно добавить, тогда вот у нас получается, вы хотите добавить, вот вы хотите добавить

701:40

Speaker C

лук, только уже у нас тут будет не лук, у нас будет что-то другое. То есть вы хотите добавить. О'кей, пока что мы научились понимать, что пользователь хочет что-то добавить. Иначе, если у нас cmd удалить тогда получается вы хотите вы, кажется, хотите удалить

701:59

Speaker C

что-то. Пока что мы ещё не умеем понимать, что именно. Вы, кажется, хотите удалить. Иначе, если команда у меня равна help, да, тогда получается нужно вывести список доступных команд. А список доступных команд у нас выглядит следующим образом.

702:19

Speaker C

Команда добавить. И после неё что нужно добавить? Эта команда позволяет добавлять что-то. И в конце каждого вывода я буду пустые строчки делать, чтобы разделять наши выводы. Вот. А, и также у нас, то есть, если вообще и не добавить, не удалите, не helpп, тогда вы

702:42

Speaker C

ввели неизвестную команду. Вывели неизвестную команду. О'кей. А, кажется, мы уже близки к тому, чтобы выполнить наше задание. Давайте запустим программу.

702:55

Speaker C

Введите команду. Ну вот я введу какую-нибудь крокозябру. Опа, вы ввели неизвестную команду. О'кей, теперь я введу, например, help. Ага, команда help. Ну вот и выявилось то, что у нас help. Ну у нас тут ещё, по-хорошему нужно сказать, что у нас есть вообще-то

703:09

Speaker C

команда ещё удалить. А что нужно удалить? Эта команда позволяет удалять что-то. О'кей. Ну и, собственно, сама команда help тоже является нашей командой, да? Поэтому команда help эта команда выводит список доступных команд. Help. Оп, всё. Команда help.

703:32

Speaker C

Команда help вводит список доступных команд. То есть мы с помощью того, что мы ввели help, мы с вами у нас посмотрели, какой список доступных команд есть. Ну вот тут вот я удалю, чтобы не дублировалось всё-таки. Ещё раз запустим. Help. Всё, команда help.

703:47

Speaker C

Теперь, если мы ведём что-то неизвестное, вы ввели неизвестную команду. Теперь, если мы ведём добавить лук, вы хотите добавить, но мы вот ещё не умеем читать вот этот вот лук. Ну, если мы хотим, например, удалить чеснок, вы хотите удалить, но

704:03

Speaker C

вот опять же мы ещё не знаем, что мы хотим удалить. Вроде как мы уже близки к нашей цели, да? Но, во-первых, тут есть уже в этой программе некоторые проблемы.

704:12

Speaker C

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

704:27

Speaker C

всё. Я благодаря этому не буду переносить курсор на новую строку после вывода, а значит, и продолжать свой ввод я буду на той же строчке.

704:35

Speaker C

Во-вторых, давайте посмотрим, что будет, если мы ничего не введём и нажмём Enter. Паника. Почему паника? Потому что мы ничего не ввели. Нажали Enter, у нас прочитался пустой текст. Этот пустой текст разбился на слова, и у нас ноль слов. Там не было никаких слов. Мы

704:50

Speaker C

получили пустой слайс. И мы из пустого слайса попытались взять первый элемент. А как бы у нас слайс пустой, там никаких элементов нету, поэтому такая ошибка.

704:58

Speaker C

Это значит, что если у нас fields равно 0, то есть длина fields равна нулю, это значит, что там нет слов. И тогда я выведу на экран. Вы ничего не [аплодисменты] ввели. Ну вот я просто нажимаю Enter, вы ничего не ввели. Но у меня всё равно

705:14

Speaker C

ошибка, потому что функцию нужно завершить, потому что иначе выполнение программы пойдёт дальше. Мы опять столкнёмся с ошибкой. Оп, вы ничего не вели. Круто. Теперь нам осталось научиться читать, что же пользователь хочет удалить или добавить после команды. То есть

705:31

Speaker C

добавить 1 2 3. И вот вот это вот 1 2 3 как прочитать? На самом деле можно по-разному это делать. Есть красивые способы, но так как мы сейчас с вами умеем не особо-то и много, то воспользуемся костылём. Вот добавить. Вы

705:44

Speaker C

хотите добавить, но что добавить? До этого нужно понять. Нам просто можно создать переменную strю, то есть пустую строчку и пройтись по каждому нашему fields от одного до конца fields и в переменную понапихать то, что там осталось, добавляя пробелы везде, кроме

706:10

Speaker C

самого последнего слова. [аплодисменты] Таким образом мы получим вот эту вот оставшуюся нашу строчку и сможем вывести её на экран. Вы хотите добавить, и здесь я выведу через двоеточие вот это вот.

706:28

Speaker C

Давайте посмотрим. Ввезите команду добавить чеснок, лук, брокколи. Оп. Мы, во-первых, поняли по первой команде, что мы именно добавляем, что мы вызываем добавление. И всё остальное мы смогли тоже прочитать и собрать это обратно в строку и вывести на экран. То есть, что

706:46

Speaker C

тут вообще произошло. Я в наших словах, да, вот в этих вот fields, которые у меня были введены, я пошёл не с самого первого слова, а со второго, да? То есть индекс один - это значит второе слово.

706:58

Speaker C

Почему? Потому что первое слово у меня отведено под команду. Значит, мне вот эти все остальные слова нужно начинать со второго слова, ну или же с первого индекса. Я пошёл с первого индекса и просто все эти слова собрал в одну

707:10

Speaker C

строчку. При помощи конкатинации строк я собрал вот этот вот вот это вот условие, оно означает, что я буду добавлять пробел между словами всегда, за исключением того, что я уже на последнем слове. То есть, если я на последнем слове, да, то есть, если у меня i уже

707:27

Speaker C

стал равен len fields -1, то есть i стал равен последнему возможному индексу, тогда я не буду добавлять пробел, чтобы, ну, в конце вот пробел, ну, зачем-то не оставлять. Мне нужен пробел только между словами. Такую же конструкцию мы можем

707:39

Speaker C

добавить в удаление. Абсолютно то же самое. Вы хотите удалить. И здесь str. Давайте запустим.

707:49

Speaker C

Видите команду, например, help. Вот наш help. Теперь мы можем добавить чеснок, лук, брокколи. Ага. И можем запустить ещё раз и удалить Souls. Всё, у нас программа работает. Давайте ещё неизвестную команду попробуем ввести.

708:06

Speaker C

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

708:23

Speaker C

тогда программа завершится. А если я вёл что-нибудь другое, то программа бы продолжала своё выполнение. Ну для этого я вот это вот всё запихну в бесконечный цикл, да? То есть я буду читать и обрабатывать команды в бесконечном цикле. Вот он наш бесконечный цикл. И я

708:42

Speaker C

буду завершать нашу функцию только если у меня команда выйти. Если команда выйти, тогда я напишу до скорого и завершу выполнение нашей функции main. Давайте посмотрим, как это работает. Ну, например, help. Оп, я ввёл Help, а у меня программа вывела команду,

709:02

Speaker C

отработала команду и не завершилась. Теперь я могу тут написать, например, добавить лук, чеснок, огурец, помидор.

709:12

Speaker C

Вы хотите добавить лук, чеснок, огурец, помидор. И опять я могу вводить кома. Я могу ввести удалить приправы. Вы хотите удалить приправы? Теперь я напишу что-нибудь непонятное. Он мне будет говорить, что я вёл неизвестную команду.

709:24

Speaker C

Я опять могу написать help, чтобы посмотреть список команд. И теперь я напишу выйти. И программа завершилась.

709:30

Speaker C

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

709:45

Speaker C

материалы. А на этом первая часть подошла к концу. Напоминаю, что домашние задания и исходные коды с наших уроков находятся в моём открытом Telegram-канале, а видео с решениями домашних заданий, видео с решением учебного проекта в приватном сообществе.

710:02

Speaker C

Всем большое спасибо за просмотр и встретимся в следующей части.

Topics: Go Golang программирование курс для начинающих Visual Studio Code установка Go настройка окружения домашние задания Telegram канал учебный проект

Учить по этому видео

- [Карточки по этому видео](https://sozai.app/ru/tools/ai-flashcard-generator/?from=transcript&id=81351)
- [Тест по этому видео](https://sozai.app/ru/tools/quiz-generator/?from=transcript&id=81351)

Бесплатно, составлено ИИ по этой расшифровке. Без регистрации.


---
This is the markdown twin of https://sozai.app/transcript/golang-full-course-beginners-part1-basics/ — the same content, without the markup.
Published by SozAI (https://sozai.app). Reuse and quotation are allowed with attribution and a link back.
Machine-readable index: https://sozai.app/llms.txt · data API: https://sozai.app/api/
